Commit 0788f64b authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/network-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents ca377000 7669c7cc
...@@ -2073,7 +2073,8 @@ ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound) ...@@ -2073,7 +2073,8 @@ ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound)
case CCP_CONFACK: case CCP_CONFACK:
if ((ppp->flags & (SC_CCP_OPEN | SC_CCP_UP)) != SC_CCP_OPEN) if ((ppp->flags & (SC_CCP_OPEN | SC_CCP_UP)) != SC_CCP_OPEN)
break; break;
if (!pskb_may_pull(skb, len = CCP_LENGTH(dp)) + 2) len = CCP_LENGTH(dp);
if (!pskb_may_pull(skb, len + 2))
return; /* too short */ return; /* too short */
dp += CCP_HDRLEN; dp += CCP_HDRLEN;
len -= CCP_HDRLEN; len -= CCP_HDRLEN;
......
...@@ -605,7 +605,18 @@ int __init tun_init(void) ...@@ -605,7 +605,18 @@ int __init tun_init(void)
void tun_cleanup(void) void tun_cleanup(void)
{ {
struct net_device *dev, *nxt;
misc_deregister(&tun_miscdev); misc_deregister(&tun_miscdev);
rtnl_lock();
for (dev = dev_base; dev; dev = nxt) {
nxt = dev->next;
if (dev->init == tun_net_init)
unregister_netdevice(dev);
}
rtnl_unlock();
} }
module_init(tun_init); module_init(tun_init);
......
...@@ -185,10 +185,9 @@ struct compressor { ...@@ -185,10 +185,9 @@ struct compressor {
#define DEFLATE_MIN_SIZE 9 #define DEFLATE_MIN_SIZE 9
#define DEFLATE_MAX_SIZE 15 #define DEFLATE_MAX_SIZE 15
#define DEFLATE_METHOD_VAL 8 #define DEFLATE_METHOD_VAL 8
#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) #define DEFLATE_SIZE(x) (((x) >> 4) + 8)
#define DEFLATE_METHOD(x) ((x) & 0x0F) #define DEFLATE_METHOD(x) ((x) & 0x0F)
#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ #define DEFLATE_MAKE_OPT(w) ((((w) - 8) << 4) + DEFLATE_METHOD_VAL)
+ DEFLATE_METHOD_VAL)
#define DEFLATE_CHK_SEQUENCE 0 #define DEFLATE_CHK_SEQUENCE 0
/* /*
......
...@@ -37,6 +37,7 @@ struct xfrm_selector ...@@ -37,6 +37,7 @@ struct xfrm_selector
__u16 dport_mask; __u16 dport_mask;
__u16 sport; __u16 sport;
__u16 sport_mask; __u16 sport_mask;
__u16 family;
__u8 prefixlen_d; __u8 prefixlen_d;
__u8 prefixlen_s; __u8 prefixlen_s;
__u8 proto; __u8 proto;
...@@ -125,6 +126,7 @@ enum ...@@ -125,6 +126,7 @@ enum
struct xfrm_user_tmpl { struct xfrm_user_tmpl {
struct xfrm_id id; struct xfrm_id id;
__u16 family;
xfrm_address_t saddr; xfrm_address_t saddr;
__u32 reqid; __u32 reqid;
__u8 mode; __u8 mode;
...@@ -189,7 +191,6 @@ struct xfrm_userpolicy_info { ...@@ -189,7 +191,6 @@ struct xfrm_userpolicy_info {
struct xfrm_lifetime_cur curlft; struct xfrm_lifetime_cur curlft;
__u32 priority; __u32 priority;
__u32 index; __u32 index;
__u16 family;
__u8 dir; __u8 dir;
__u8 action; __u8 action;
#define XFRM_POLICY_ALLOW 0 #define XFRM_POLICY_ALLOW 0
......
...@@ -353,9 +353,7 @@ extern int ip6_push_pending_frames(struct sock *sk); ...@@ -353,9 +353,7 @@ extern int ip6_push_pending_frames(struct sock *sk);
extern void ip6_flush_pending_frames(struct sock *sk); extern void ip6_flush_pending_frames(struct sock *sk);
extern int ip6_dst_lookup(struct sock *sk, extern struct dst_entry * ip6_dst_lookup(struct sock *sk, struct flowi *fl);
struct dst_entry **dst,
struct flowi *fl);
/* /*
* skb processing functions * skb processing functions
......
...@@ -279,6 +279,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x) ...@@ -279,6 +279,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
t->props.family = AF_INET; t->props.family = AF_INET;
t->props.mode = 1; t->props.mode = 1;
t->props.saddr.a4 = x->props.saddr.a4; t->props.saddr.a4 = x->props.saddr.a4;
t->props.flags = x->props.flags;
t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family); t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family);
if (t->type == NULL) if (t->type == NULL)
......
...@@ -27,6 +27,20 @@ static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff ...@@ -27,6 +27,20 @@ static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff
IP_ECN_set_ce(inner_iph); IP_ECN_set_ce(inner_iph);
} }
static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
{
switch (nexthdr) {
case IPPROTO_IPIP:
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
return -EINVAL;
*spi = skb->nh.iph->saddr;
*seq = 0;
return 0;
}
return xfrm_parse_spi(skb, nexthdr, spi, seq);
}
int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
{ {
int err; int err;
...@@ -36,7 +50,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) ...@@ -36,7 +50,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
int xfrm_nr = 0; int xfrm_nr = 0;
int decaps = 0; int decaps = 0;
if ((err = xfrm_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) != 0) if ((err = xfrm4_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) != 0)
goto drop; goto drop;
do { do {
......
...@@ -83,31 +83,8 @@ static int ipip_output(struct sk_buff *skb) ...@@ -83,31 +83,8 @@ static int ipip_output(struct sk_buff *skb)
return err; return err;
} }
static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff *skb)
{
struct iphdr *inner_iph = skb->nh.iph;
if (INET_ECN_is_ce(outer_iph->tos) &&
INET_ECN_is_not_ce(inner_iph->tos))
IP_ECN_set_ce(inner_iph);
}
static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
{ {
struct iphdr *outer_iph = skb->nh.iph;
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
return -EINVAL;
skb->mac.raw = skb->nh.raw;
skb->nh.raw = skb->data;
memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
dst_release(skb->dst);
skb->dst = NULL;
skb->protocol = htons(ETH_P_IP);
skb->pkt_type = PACKET_HOST;
ipip_ecn_decapsulate(outer_iph, skb);
netif_rx(skb);
return 0; return 0;
} }
...@@ -149,46 +126,12 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler) ...@@ -149,46 +126,12 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler)
static int ipip_rcv(struct sk_buff *skb) static int ipip_rcv(struct sk_buff *skb)
{ {
struct xfrm_tunnel *handler = ipip_handler; struct xfrm_tunnel *handler = ipip_handler;
struct xfrm_state *x = NULL;
int err;
/* Tunnel devices take precedence. */ /* Tunnel devices take precedence. */
if (handler) { if (handler && handler->handler(skb) == 0)
err = handler->handler(skb); return 0;
if (!err)
goto out;
}
x = xfrm_state_lookup((xfrm_address_t *)&skb->nh.iph->daddr, return xfrm4_rcv_encap(skb, 0);
skb->nh.iph->saddr,
IPPROTO_IPIP, AF_INET);
if (!x)
goto drop;
spin_lock(&x->lock);
if (unlikely(x->km.state != XFRM_STATE_VALID))
goto drop_unlock;
err = ipip_xfrm_rcv(x, NULL, skb);
if (err)
goto drop_unlock;
x->curlft.bytes += skb->len;
x->curlft.packets++;
spin_unlock(&x->lock);
xfrm_state_put(x);
out:
return err;
drop_unlock:
spin_unlock(&x->lock);
xfrm_state_put(x);
drop:
err = NET_RX_DROP;
kfree_skb(skb);
goto out;
} }
static void ipip_err(struct sk_buff *skb, u32 info) static void ipip_err(struct sk_buff *skb, u32 info)
......
...@@ -265,13 +265,12 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu ...@@ -265,13 +265,12 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
* There is offset of AH before IPv6 header after the process. * There is offset of AH before IPv6 header after the process.
*/ */
struct ipv6hdr *iph = skb->nh.ipv6h;
struct ipv6_auth_hdr *ah; struct ipv6_auth_hdr *ah;
struct ah_data *ahp; struct ah_data *ahp;
unsigned char *tmp_hdr = NULL; unsigned char *tmp_hdr = NULL;
u16 hdr_len = skb->data - skb->nh.raw; u16 hdr_len;
u16 ah_hlen; u16 ah_hlen;
u16 cleared_hlen = hdr_len; u16 cleared_hlen;
u16 nh_offset = 0; u16 nh_offset = 0;
u8 nexthdr = 0; u8 nexthdr = 0;
u8 *prevhdr; u8 *prevhdr;
...@@ -279,6 +278,14 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu ...@@ -279,6 +278,14 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr))) if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr)))
goto out; goto out;
/* We are going to _remove_ AH header to keep sockets happy,
* so... Later this can change. */
if (skb_cloned(skb) &&
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto out;
hdr_len = skb->data - skb->nh.raw;
cleared_hlen = hdr_len;
ah = (struct ipv6_auth_hdr*)skb->data; ah = (struct ipv6_auth_hdr*)skb->data;
ahp = x->data; ahp = x->data;
nexthdr = ah->nexthdr; nexthdr = ah->nexthdr;
...@@ -297,27 +304,22 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu ...@@ -297,27 +304,22 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
if (!pskb_may_pull(skb, ah_hlen)) if (!pskb_may_pull(skb, ah_hlen))
goto out; goto out;
/* We are going to _remove_ AH header to keep sockets happy,
* so... Later this can change. */
if (skb_cloned(skb) &&
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto out;
tmp_hdr = kmalloc(cleared_hlen, GFP_ATOMIC); tmp_hdr = kmalloc(cleared_hlen, GFP_ATOMIC);
if (!tmp_hdr) if (!tmp_hdr)
goto out; goto out;
memcpy(tmp_hdr, skb->nh.raw, cleared_hlen); memcpy(tmp_hdr, skb->nh.raw, cleared_hlen);
ipv6_clear_mutable_options(skb, &nh_offset, XFRM_POLICY_IN); ipv6_clear_mutable_options(skb, &nh_offset, XFRM_POLICY_IN);
iph->priority = 0; skb->nh.ipv6h->priority = 0;
iph->flow_lbl[0] = 0; skb->nh.ipv6h->flow_lbl[0] = 0;
iph->flow_lbl[1] = 0; skb->nh.ipv6h->flow_lbl[1] = 0;
iph->flow_lbl[2] = 0; skb->nh.ipv6h->flow_lbl[2] = 0;
iph->hop_limit = 0; skb->nh.ipv6h->hop_limit = 0;
{ {
u8 auth_data[ahp->icv_trunc_len]; u8 auth_data[ahp->icv_trunc_len];
memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
memset(ah->auth_data, 0, ahp->icv_trunc_len);
skb_push(skb, skb->data - skb->nh.raw); skb_push(skb, skb->data - skb->nh.raw);
ahp->icv(ahp, skb, ah->auth_data); ahp->icv(ahp, skb, ah->auth_data);
if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) {
......
...@@ -355,8 +355,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, ...@@ -355,8 +355,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
fl.oif = np->mcast_oif; fl.oif = np->mcast_oif;
err = ip6_dst_lookup(sk, &dst, &fl); dst = ip6_dst_lookup(sk, &fl);
if (err) goto out; if (dst->error) goto out;
if (hlimit < 0) { if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl.fl6_dst)) if (ipv6_addr_is_multicast(&fl.fl6_dst))
...@@ -434,9 +434,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb) ...@@ -434,9 +434,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
fl.oif = np->mcast_oif; fl.oif = np->mcast_oif;
err = ip6_dst_lookup(sk, &dst, &fl); dst = ip6_dst_lookup(sk, &fl);
if (err) goto out; if (dst->error) goto out;
if (hlimit < 0) { if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl.fl6_dst)) if (ipv6_addr_is_multicast(&fl.fl6_dst))
......
...@@ -209,11 +209,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, ...@@ -209,11 +209,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
int seg_len = skb->len; int seg_len = skb->len;
int hlimit; int hlimit;
u32 mtu; u32 mtu;
int err = 0;
if ((err = xfrm_lookup(&skb->dst, fl, sk, 0)) < 0) {
return err;
}
if (opt) { if (opt) {
int head_room; int head_room;
...@@ -1141,72 +1136,73 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) ...@@ -1141,72 +1136,73 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
return err; return err;
} }
int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) struct dst_entry *ip6_dst_lookup(struct sock *sk, struct flowi *fl)
{ {
struct ipv6_pinfo *np = inet6_sk(sk); struct dst_entry *dst = NULL;
int err = 0; int err = 0;
*dst = __sk_dst_check(sk, np->dst_cookie); if (sk) {
if (*dst) { struct ipv6_pinfo *np = inet6_sk(sk);
struct rt6_info *rt = (struct rt6_info*)*dst;
dst = __sk_dst_check(sk, np->dst_cookie);
/* Yes, checking route validity in not connected if (dst) {
case is not very simple. Take into account, struct rt6_info *rt = (struct rt6_info*)dst;
that we do not support routing by source, TOS,
and MSG_DONTROUTE --ANK (980726) /* Yes, checking route validity in not connected
case is not very simple. Take into account,
1. If route was host route, check that that we do not support routing by source, TOS,
cached destination is current. and MSG_DONTROUTE --ANK (980726)
If it is network route, we still may
check its validity using saved pointer 1. If route was host route, check that
to the last used address: daddr_cache. cached destination is current.
We do not want to save whole address now, If it is network route, we still may
(because main consumer of this service check its validity using saved pointer
is tcp, which has not this problem), to the last used address: daddr_cache.
so that the last trick works only on connected We do not want to save whole address now,
sockets. (because main consumer of this service
2. oif also should be the same. is tcp, which has not this problem),
*/ so that the last trick works only on connected
sockets.
if (((rt->rt6i_dst.plen != 128 || 2. oif also should be the same.
ipv6_addr_cmp(&fl->fl6_dst, &rt->rt6i_dst.addr)) */
&& (np->daddr_cache == NULL ||
ipv6_addr_cmp(&fl->fl6_dst, np->daddr_cache))) if (((rt->rt6i_dst.plen != 128 ||
|| (fl->oif && fl->oif != (*dst)->dev->ifindex)) { ipv6_addr_cmp(&fl->fl6_dst, &rt->rt6i_dst.addr))
*dst = NULL; && (np->daddr_cache == NULL ||
} else ipv6_addr_cmp(&fl->fl6_dst, np->daddr_cache)))
dst_hold(*dst); || (fl->oif && fl->oif != dst->dev->ifindex)) {
dst = NULL;
} else
dst_hold(dst);
}
} }
if (*dst == NULL) if (dst == NULL)
*dst = ip6_route_output(sk, fl); dst = ip6_route_output(sk, fl);
if ((*dst)->error) { if (dst->error)
IP6_INC_STATS(Ip6OutNoRoutes); return dst;
dst_release(*dst);
return -ENETUNREACH;
}
if (ipv6_addr_any(&fl->fl6_src)) { if (ipv6_addr_any(&fl->fl6_src)) {
err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); err = ipv6_get_saddr(dst, &fl->fl6_dst, &fl->fl6_src);
if (err) { if (err) {
#if IP6_DEBUG >= 2 #if IP6_DEBUG >= 2
printk(KERN_DEBUG "ip6_build_xmit: " printk(KERN_DEBUG "ip6_build_xmit: "
"no available source address\n"); "no available source address\n");
#endif #endif
return err; dst->error = err;
return dst;
} }
} }
if (*dst) { if (dst) {
if ((err = xfrm_lookup(dst, fl, sk, 0)) < 0) { if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) {
dst_release(*dst); dst->error = -ENETUNREACH;
return -ENETUNREACH;
} }
} }
return 0; return dst;
} }
int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb),
......
...@@ -621,6 +621,14 @@ merge_options(struct sock *sk, __u8 encap_limit, ...@@ -621,6 +621,14 @@ merge_options(struct sock *sk, __u8 encap_limit,
return opt; return opt;
} }
static int
ip6ip6_getfrag(void *from, char *to, int offset, int len, int odd,
struct sk_buff *skb)
{
memcpy(to, (char *) from + offset, len);
return 0;
}
/** /**
* ip6ip6_tnl_addr_conflict - compare packet addresses to tunnel's own * ip6ip6_tnl_addr_conflict - compare packet addresses to tunnel's own
* @t: the outgoing tunnel device * @t: the outgoing tunnel device
...@@ -755,9 +763,9 @@ int ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -755,9 +763,9 @@ int ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
} }
if (skb->len > mtu) { if (skb->len > mtu) {
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
goto tx_err_opt_release; goto tx_err_dst_release;
} }
err = ip6_append_data(sk, ip_generic_getfrag, skb->nh.raw, skb->len, 0, err = ip6_append_data(sk, ip6ip6_getfrag, skb->nh.raw, skb->len, 0,
t->parms.hop_limit, opt, &fl, t->parms.hop_limit, opt, &fl,
(struct rt6_info *)dst, MSG_DONTWAIT); (struct rt6_info *)dst, MSG_DONTWAIT);
...@@ -785,7 +793,6 @@ int ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -785,7 +793,6 @@ int ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
return 0; return 0;
tx_err_dst_release: tx_err_dst_release:
dst_release(dst); dst_release(dst);
tx_err_opt_release:
if (opt && opt != orig_opt) if (opt && opt != orig_opt)
sock_kfree_s(sk, opt, opt->tot_len); sock_kfree_s(sk, opt, opt->tot_len);
tx_err_free_fl_lbl: tx_err_free_fl_lbl:
......
...@@ -658,8 +658,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg ...@@ -658,8 +658,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
fl.oif = np->mcast_oif; fl.oif = np->mcast_oif;
err = ip6_dst_lookup(sk, &dst, &fl); dst = ip6_dst_lookup(sk, &fl);
if (err) if ((err = dst->error))
goto out; goto out;
if (hlimit < 0) { if (hlimit < 0) {
......
...@@ -663,7 +663,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, ...@@ -663,7 +663,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
ipv6_addr_copy(&fl.fl6_dst, rt0->addr); ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
} }
dst = ip6_route_output(sk, &fl); dst = ip6_dst_lookup(sk, &fl);
if ((err = dst->error) != 0) { if ((err = dst->error) != 0) {
dst_release(dst); dst_release(dst);
...@@ -691,6 +691,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, ...@@ -691,6 +691,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
tp->ext_header_len = 0; tp->ext_header_len = 0;
if (np->opt) if (np->opt)
tp->ext_header_len = np->opt->opt_flen + np->opt->opt_nflen; tp->ext_header_len = np->opt->opt_flen + np->opt->opt_nflen;
tp->ext2_header_len = dst->header_len;
tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
inet->dport = usin->sin6_port; inet->dport = usin->sin6_port;
...@@ -788,7 +790,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -788,7 +790,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
fl.fl_ip_dport = inet->dport; fl.fl_ip_dport = inet->dport;
fl.fl_ip_sport = inet->sport; fl.fl_ip_sport = inet->sport;
dst = ip6_route_output(sk, &fl); dst = ip6_dst_lookup(sk, &fl);
} else } else
dst_hold(dst); dst_hold(dst);
...@@ -889,7 +891,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req, ...@@ -889,7 +891,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
ipv6_addr_copy(&fl.fl6_dst, rt0->addr); ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
} }
dst = ip6_route_output(sk, &fl); dst = ip6_dst_lookup(sk, &fl);
if (dst->error) if (dst->error)
goto done; goto done;
} }
...@@ -1018,7 +1020,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb) ...@@ -1018,7 +1020,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
fl.fl_ip_sport = t1->source; fl.fl_ip_sport = t1->source;
/* sk = NULL, but it is safe for now. RST socket required. */ /* sk = NULL, but it is safe for now. RST socket required. */
buff->dst = ip6_route_output(NULL, &fl); buff->dst = ip6_dst_lookup(NULL, &fl);
if (buff->dst->error == 0) { if (buff->dst->error == 0) {
ip6_xmit(NULL, buff, &fl, NULL, 0); ip6_xmit(NULL, buff, &fl, NULL, 0);
...@@ -1081,7 +1083,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ...@@ -1081,7 +1083,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
fl.fl_ip_dport = t1->dest; fl.fl_ip_dport = t1->dest;
fl.fl_ip_sport = t1->source; fl.fl_ip_sport = t1->source;
buff->dst = ip6_route_output(NULL, &fl); buff->dst = ip6_dst_lookup(NULL, &fl);
if (buff->dst->error == 0) { if (buff->dst->error == 0) {
ip6_xmit(NULL, buff, &fl, NULL, 0); ip6_xmit(NULL, buff, &fl, NULL, 0);
...@@ -1329,7 +1331,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, ...@@ -1329,7 +1331,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
fl.fl_ip_dport = req->rmt_port; fl.fl_ip_dport = req->rmt_port;
fl.fl_ip_sport = inet_sk(sk)->sport; fl.fl_ip_sport = inet_sk(sk)->sport;
dst = ip6_route_output(sk, &fl); dst = ip6_dst_lookup(sk, &fl);
} }
if (dst->error) if (dst->error)
...@@ -1401,6 +1403,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, ...@@ -1401,6 +1403,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
if (newnp->opt) if (newnp->opt)
newtp->ext_header_len = newnp->opt->opt_nflen + newtp->ext_header_len = newnp->opt->opt_nflen +
newnp->opt->opt_flen; newnp->opt->opt_flen;
newtp->ext2_header_len = dst->header_len;
tcp_sync_mss(newsk, dst_pmtu(dst)); tcp_sync_mss(newsk, dst_pmtu(dst));
newtp->advmss = dst_metric(dst, RTAX_ADVMSS); newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
...@@ -1727,7 +1730,7 @@ static int tcp_v6_rebuild_header(struct sock *sk) ...@@ -1727,7 +1730,7 @@ static int tcp_v6_rebuild_header(struct sock *sk)
ipv6_addr_copy(&fl.fl6_dst, rt0->addr); ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
} }
dst = ip6_route_output(sk, &fl); dst = ip6_dst_lookup(sk, &fl);
if (dst->error) { if (dst->error) {
err = dst->error; err = dst->error;
...@@ -1770,7 +1773,7 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok) ...@@ -1770,7 +1773,7 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
dst = __sk_dst_check(sk, np->dst_cookie); dst = __sk_dst_check(sk, np->dst_cookie);
if (dst == NULL) { if (dst == NULL) {
dst = ip6_route_output(sk, &fl); dst = ip6_dst_lookup(sk, &fl);
if (dst->error) { if (dst->error) {
sk->sk_err_soft = -dst->error; sk->sk_err_soft = -dst->error;
......
...@@ -811,8 +811,10 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg ...@@ -811,8 +811,10 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
* The socket lock must be held while it's corked. * The socket lock must be held while it's corked.
*/ */
lock_sock(sk); lock_sock(sk);
if (likely(up->pending)) if (likely(up->pending)) {
dst = NULL;
goto do_append_data; goto do_append_data;
}
release_sock(sk); release_sock(sk);
} }
ulen += sizeof(struct udphdr); ulen += sizeof(struct udphdr);
...@@ -928,8 +930,8 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg ...@@ -928,8 +930,8 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
fl.oif = np->mcast_oif; fl.oif = np->mcast_oif;
err = ip6_dst_lookup(sk, &dst, &fl); dst = ip6_dst_lookup(sk, &fl);
if (err) if ((err = dst->error))
goto out; goto out;
if (hlimit < 0) { if (hlimit < 0) {
...@@ -968,9 +970,10 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg ...@@ -968,9 +970,10 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
else if (!corkreq) else if (!corkreq)
err = udp_v6_push_pending_frames(sk, up); err = udp_v6_push_pending_frames(sk, up);
ip6_dst_store(sk, dst, if (dst)
!ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ? ip6_dst_store(sk, dst,
&np->daddr : NULL); !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
&np->daddr : NULL);
if (err > 0) if (err > 0)
err = np->recverr ? net_xmit_errno(err) : 0; err = np->recverr ? net_xmit_errno(err) : 0;
release_sock(sk); release_sock(sk);
......
...@@ -482,10 +482,8 @@ EXPORT_SYMBOL(sysctl_tcp_tw_recycle); ...@@ -482,10 +482,8 @@ EXPORT_SYMBOL(sysctl_tcp_tw_recycle);
EXPORT_SYMBOL(sysctl_max_syn_backlog); EXPORT_SYMBOL(sysctl_max_syn_backlog);
#endif #endif
#endif
#if defined (CONFIG_IPV6_MODULE) || defined (CONFIG_IP_SCTP_MODULE) || defined (CONFIG_IPV6_TUNNEL_MODULE)
EXPORT_SYMBOL(ip_generic_getfrag); EXPORT_SYMBOL(ip_generic_getfrag);
#endif #endif
EXPORT_SYMBOL(tcp_read_sock); EXPORT_SYMBOL(tcp_read_sock);
......
...@@ -527,7 +527,7 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) ...@@ -527,7 +527,7 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
return -EINVAL; return -EINVAL;
}; };
switch (p->family) { switch (p->sel.family) {
case AF_INET: case AF_INET:
break; break;
...@@ -594,7 +594,7 @@ static void copy_from_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy ...@@ -594,7 +594,7 @@ static void copy_from_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy
memcpy(&xp->lft, &p->lft, sizeof(xp->lft)); memcpy(&xp->lft, &p->lft, sizeof(xp->lft));
xp->action = p->action; xp->action = p->action;
xp->flags = p->flags; xp->flags = p->flags;
xp->family = p->family; xp->family = p->sel.family;
/* XXX xp->share = p->share; */ /* XXX xp->share = p->share; */
} }
...@@ -605,7 +605,7 @@ static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_i ...@@ -605,7 +605,7 @@ static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_i
memcpy(&p->curlft, &xp->curlft, sizeof(p->curlft)); memcpy(&p->curlft, &xp->curlft, sizeof(p->curlft));
p->priority = xp->priority; p->priority = xp->priority;
p->index = xp->index; p->index = xp->index;
p->family = xp->family; p->sel.family = xp->family;
p->dir = dir; p->dir = dir;
p->action = xp->action; p->action = xp->action;
p->flags = xp->flags; p->flags = xp->flags;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment