Commit b60485d6 authored by David S. Miller's avatar David S. Miller

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

into kernel.bkbits.net:/home/davem/net-2.5
parents 02ab55b8 7cba2d48
...@@ -844,7 +844,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -844,7 +844,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (ns == 0) if (ns == 0)
goto outf; goto outf;
skb_reserve(ns, dev->hard_header_len); skb_reserve(ns, dev->hard_header_len);
memcpy(skb_put(ns, skb->len), skb->data, skb->len); skb_copy_bits(skb, 0, skb_put(ns, skb->len), skb->len);
kfree_skb(skb); kfree_skb(skb);
skb = ns; skb = ns;
} }
...@@ -1455,7 +1455,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) ...@@ -1455,7 +1455,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
goto err; goto err;
} }
skb_reserve(ns, 2); skb_reserve(ns, 2);
memcpy(skb_put(ns, skb->len), skb->data, skb->len); skb_copy_bits(skb, 0, skb_put(ns, skb->len), skb->len);
kfree_skb(skb); kfree_skb(skb);
skb = ns; skb = ns;
} }
...@@ -1826,7 +1826,7 @@ ppp_mp_reconstruct(struct ppp *ppp) ...@@ -1826,7 +1826,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
if (head != tail) if (head != tail)
/* copy to a single skb */ /* copy to a single skb */
for (p = head; p != tail->next; p = p->next) for (p = head; p != tail->next; p = p->next)
memcpy(skb_put(skb, p->len), p->data, p->len); skb_copy_bits(p, 0, skb_put(skb, p->len), p->len);
ppp->nextseq = tail->sequence + 1; ppp->nextseq = tail->sequence + 1;
head = tail->next; head = tail->next;
} }
......
...@@ -1521,6 +1521,12 @@ static int happy_meal_init(struct happy_meal *hp) ...@@ -1521,6 +1521,12 @@ static int happy_meal_init(struct happy_meal *hp)
hme_write32(hp, bregs + BMAC_IGAP1, DEFAULT_IPG1); hme_write32(hp, bregs + BMAC_IGAP1, DEFAULT_IPG1);
hme_write32(hp, bregs + BMAC_IGAP2, DEFAULT_IPG2); hme_write32(hp, bregs + BMAC_IGAP2, DEFAULT_IPG2);
/* Make sure we can handle VLAN frames. */
hme_write32(hp, bregs + BMAC_TXMAX,
ETH_DATA_LEN + ETH_HLEN + 8);
hme_write32(hp, bregs + BMAC_RXMAX,
ETH_DATA_LEN + ETH_HLEN + 8);
/* Load up the MAC address and random seed. */ /* Load up the MAC address and random seed. */
HMD(("rseed/macaddr, ")); HMD(("rseed/macaddr, "));
......
...@@ -276,8 +276,10 @@ static inline void ipv6_addr_prefix(struct in6_addr *pfx, ...@@ -276,8 +276,10 @@ static inline void ipv6_addr_prefix(struct in6_addr *pfx,
b = plen & 0x7; b = plen & 0x7;
memcpy(pfx->s6_addr, addr, o); memcpy(pfx->s6_addr, addr, o);
if (b != 0) if (b != 0) {
pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b); pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b);
o++;
}
if (o < 16) if (o < 16)
memset(pfx->s6_addr + o, 0, 16 - o); memset(pfx->s6_addr + o, 0, 16 - o);
} }
......
...@@ -628,13 +628,6 @@ static inline void tcp_openreq_free(struct open_request *req) ...@@ -628,13 +628,6 @@ static inline void tcp_openreq_free(struct open_request *req)
/* /*
* Pointers to address related TCP functions * Pointers to address related TCP functions
* (i.e. things that depend on the address family) * (i.e. things that depend on the address family)
*
* BUGGG_FUTURE: all the idea behind this struct is wrong.
* It mixes socket frontend with transport function.
* With port sharing between IPv6/v4 it gives the only advantage,
* only poor IPv6 needs to permanently recheck, that it
* is still IPv6 8)8) It must be cleaned up as soon as possible.
* --ANK (980802)
*/ */
struct tcp_func { struct tcp_func {
......
...@@ -1154,6 +1154,8 @@ static int ipgre_tunnel_init(struct net_device *dev) ...@@ -1154,6 +1154,8 @@ static int ipgre_tunnel_init(struct net_device *dev)
iph = &tunnel->parms.iph; iph = &tunnel->parms.iph;
tunnel->dev = dev; tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
...@@ -1215,6 +1217,9 @@ int __init ipgre_fb_tunnel_init(struct net_device *dev) ...@@ -1215,6 +1217,9 @@ int __init ipgre_fb_tunnel_init(struct net_device *dev)
struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv; struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
struct iphdr *iph = &tunnel->parms.iph; struct iphdr *iph = &tunnel->parms.iph;
tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
iph->version = 4; iph->version = 4;
iph->protocol = IPPROTO_GRE; iph->protocol = IPPROTO_GRE;
iph->ihl = 5; iph->ihl = 5;
......
...@@ -805,7 +805,10 @@ static int ipip_tunnel_init(struct net_device *dev) ...@@ -805,7 +805,10 @@ static int ipip_tunnel_init(struct net_device *dev)
tunnel = (struct ip_tunnel*)dev->priv; tunnel = (struct ip_tunnel*)dev->priv;
iph = &tunnel->parms.iph; iph = &tunnel->parms.iph;
tunnel->dev = dev; tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
...@@ -841,6 +844,9 @@ static int __init ipip_fb_tunnel_init(struct net_device *dev) ...@@ -841,6 +844,9 @@ static int __init ipip_fb_tunnel_init(struct net_device *dev)
struct ip_tunnel *tunnel = dev->priv; struct ip_tunnel *tunnel = dev->priv;
struct iphdr *iph = &tunnel->parms.iph; struct iphdr *iph = &tunnel->parms.iph;
tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
iph->version = 4; iph->version = 4;
iph->protocol = IPPROTO_IPIP; iph->protocol = IPPROTO_IPIP;
iph->ihl = 5; iph->ihl = 5;
......
...@@ -3693,7 +3693,17 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, ...@@ -3693,7 +3693,17 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
tcp_sync_mss(sk, tp->pmtu_cookie); tcp_sync_mss(sk, tp->pmtu_cookie);
tcp_initialize_rcv_mss(sk); tcp_initialize_rcv_mss(sk);
/* Make sure socket is routed, for correct metrics. */
tp->af_specific->rebuild_header(sk);
tcp_init_metrics(sk); tcp_init_metrics(sk);
/* Prevent spurious tcp_cwnd_restart() on first data
* packet.
*/
tp->lsndtime = tcp_time_stamp;
tcp_init_buffer_space(sk); tcp_init_buffer_space(sk);
if (sock_flag(sk, SOCK_KEEPOPEN)) if (sock_flag(sk, SOCK_KEEPOPEN))
...@@ -3959,7 +3969,18 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, ...@@ -3959,7 +3969,18 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
if (tp->tstamp_ok) if (tp->tstamp_ok)
tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
/* Make sure socket is routed, for
* correct metrics.
*/
tp->af_specific->rebuild_header(sk);
tcp_init_metrics(sk); tcp_init_metrics(sk);
/* Prevent spurious tcp_cwnd_restart() on
* first data packet.
*/
tp->lsndtime = tcp_time_stamp;
tcp_initialize_rcv_mss(sk); tcp_initialize_rcv_mss(sk);
tcp_init_buffer_space(sk); tcp_init_buffer_space(sk);
tcp_fast_path_on(tp); tcp_fast_path_on(tp);
......
...@@ -87,18 +87,11 @@ static void ip6_xmit_unlock(void) ...@@ -87,18 +87,11 @@ static void ip6_xmit_unlock(void)
static int ip6ip6_fb_tnl_dev_init(struct net_device *dev); static int ip6ip6_fb_tnl_dev_init(struct net_device *dev);
static int ip6ip6_tnl_dev_init(struct net_device *dev); static int ip6ip6_tnl_dev_init(struct net_device *dev);
static void ip6ip6_tnl_dev_setup(struct net_device *dev);
/* the IPv6 tunnel fallback device */ /* the IPv6 tunnel fallback device */
static struct net_device ip6ip6_fb_tnl_dev = { static struct net_device *ip6ip6_fb_tnl_dev;
.name = "ip6tnl0",
.init = ip6ip6_fb_tnl_dev_init
};
/* the IPv6 fallback tunnel */
static struct ip6_tnl ip6ip6_fb_tnl = {
.dev = &ip6ip6_fb_tnl_dev,
.parms ={.name = "ip6tnl0", .proto = IPPROTO_IPV6}
};
/* lists for storing tunnels in use */ /* lists for storing tunnels in use */
static struct ip6_tnl *tnls_r_l[HASH_SIZE]; static struct ip6_tnl *tnls_r_l[HASH_SIZE];
...@@ -216,59 +209,39 @@ static int ...@@ -216,59 +209,39 @@ static int
ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt) ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt)
{ {
struct net_device *dev; struct net_device *dev;
int err = -ENOBUFS;
struct ip6_tnl *t; struct ip6_tnl *t;
char name[IFNAMSIZ];
int err;
dev = kmalloc(sizeof (*dev) + sizeof (*t), GFP_KERNEL); if (p->name[0]) {
if (!dev) strlcpy(name, p->name, IFNAMSIZ);
return err; } else {
int i;
for (i = 1; i < IP6_TNL_MAX; i++) {
sprintf(name, "ip6tnl%d", i);
if (__dev_get_by_name(name) == NULL)
break;
}
if (i == IP6_TNL_MAX)
return -ENOBUFS;
}
dev = alloc_netdev(sizeof (*t), name, ip6ip6_tnl_dev_setup);
if (dev == NULL)
return -ENOMEM;
memset(dev, 0, sizeof (*dev) + sizeof (*t)); t = dev->priv;
dev->priv = (void *) (dev + 1);
t = (struct ip6_tnl *) dev->priv;
t->dev = dev;
dev->init = ip6ip6_tnl_dev_init; dev->init = ip6ip6_tnl_dev_init;
memcpy(&t->parms, p, sizeof (*p)); t->parms = *p;
t->parms.name[IFNAMSIZ - 1] = '\0';
strcpy(dev->name, t->parms.name);
if (!dev->name[0]) {
int i = 0;
int exists = 0;
do {
sprintf(dev->name, "ip6tnl%d", ++i);
exists = (__dev_get_by_name(dev->name) != NULL);
} while (i < IP6_TNL_MAX && exists);
if (i == IP6_TNL_MAX) {
goto failed;
}
memcpy(t->parms.name, dev->name, IFNAMSIZ);
}
SET_MODULE_OWNER(dev);
if ((err = register_netdevice(dev)) < 0) { if ((err = register_netdevice(dev)) < 0) {
goto failed; kfree(dev);
return err;
} }
dev_hold(dev);
ip6ip6_tnl_link(t); ip6ip6_tnl_link(t);
*pt = t; *pt = t;
return 0; return 0;
failed:
kfree(dev);
return err;
}
/**
* ip6_tnl_destroy() - destroy old tunnel
* @t: tunnel to be destroyed
*
* Return:
* whatever unregister_netdevice() returns
**/
static inline int
ip6_tnl_destroy(struct ip6_tnl *t)
{
return unregister_netdevice(t->dev);
} }
/** /**
...@@ -304,21 +277,10 @@ ip6ip6_tnl_locate(struct ip6_tnl_parm *p, struct ip6_tnl **pt, int create) ...@@ -304,21 +277,10 @@ ip6ip6_tnl_locate(struct ip6_tnl_parm *p, struct ip6_tnl **pt, int create)
return (create ? -EEXIST : 0); return (create ? -EEXIST : 0);
} }
} }
if (!create) { if (!create)
return -ENODEV; return -ENODEV;
}
return ip6_tnl_create(p, pt);
}
/**
* ip6ip6_tnl_dev_destructor - tunnel device destructor
* @dev: the device to be destroyed
**/
static void return ip6_tnl_create(p, pt);
ip6ip6_tnl_dev_destructor(struct net_device *dev)
{
kfree(dev);
} }
/** /**
...@@ -332,14 +294,14 @@ ip6ip6_tnl_dev_destructor(struct net_device *dev) ...@@ -332,14 +294,14 @@ ip6ip6_tnl_dev_destructor(struct net_device *dev)
static void static void
ip6ip6_tnl_dev_uninit(struct net_device *dev) ip6ip6_tnl_dev_uninit(struct net_device *dev)
{ {
if (dev == &ip6ip6_fb_tnl_dev) { if (dev == ip6ip6_fb_tnl_dev) {
write_lock_bh(&ip6ip6_lock); write_lock_bh(&ip6ip6_lock);
tnls_wc[0] = NULL; tnls_wc[0] = NULL;
write_unlock_bh(&ip6ip6_lock); write_unlock_bh(&ip6ip6_lock);
} else { } else {
struct ip6_tnl *t = (struct ip6_tnl *) dev->priv; ip6ip6_tnl_unlink((struct ip6_tnl *) dev->priv);
ip6ip6_tnl_unlink(t);
} }
dev_put(dev);
} }
/** /**
...@@ -506,7 +468,7 @@ void ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -506,7 +468,7 @@ void ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
icmpv6_send(skb2, rel_type, rel_code, rel_info, skb2->dev); icmpv6_send(skb2, rel_type, rel_code, rel_info, skb2->dev);
if (rt) if (rt)
dst_free(&rt->u.dst); dst_release(&rt->u.dst);
kfree_skb(skb2); kfree_skb(skb2);
} }
...@@ -878,7 +840,6 @@ static void ip6_tnl_set_cap(struct ip6_tnl *t) ...@@ -878,7 +840,6 @@ static void ip6_tnl_set_cap(struct ip6_tnl *t)
} }
} }
static void ip6ip6_tnl_link_config(struct ip6_tnl *t) static void ip6ip6_tnl_link_config(struct ip6_tnl *t)
{ {
struct net_device *dev = t->dev; struct net_device *dev = t->dev;
...@@ -906,31 +867,25 @@ static void ip6ip6_tnl_link_config(struct ip6_tnl *t) ...@@ -906,31 +867,25 @@ static void ip6ip6_tnl_link_config(struct ip6_tnl *t)
if (p->flags & IP6_TNL_F_CAP_XMIT) { if (p->flags & IP6_TNL_F_CAP_XMIT) {
struct rt6_info *rt = rt6_lookup(&p->raddr, &p->laddr, struct rt6_info *rt = rt6_lookup(&p->raddr, &p->laddr,
p->link, 0); p->link, 0);
if (rt) {
struct net_device *rtdev; if (rt == NULL)
if (!(rtdev = rt->rt6i_dev) || return;
rtdev->type == ARPHRD_TUNNEL6) {
/* as long as tunnels use the same socket /* as long as tunnels use the same socket for transmission,
for transmission, locally nested tunnels locally nested tunnels won't work */
won't work */
dst_release(&rt->u.dst); if (rt->rt6i_dev && rt->rt6i_dev->type != ARPHRD_TUNNEL6) {
goto no_link; dev->iflink = rt->rt6i_dev->ifindex;
} else {
dev->iflink = rtdev->ifindex; dev->hard_header_len = rt->rt6i_dev->hard_header_len +
dev->hard_header_len = rtdev->hard_header_len +
sizeof (struct ipv6hdr); sizeof (struct ipv6hdr);
dev->mtu = rtdev->mtu - sizeof (struct ipv6hdr);
dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr);
if (dev->mtu < IPV6_MIN_MTU) if (dev->mtu < IPV6_MIN_MTU)
dev->mtu = IPV6_MIN_MTU; dev->mtu = IPV6_MIN_MTU;
dst_release(&rt->u.dst);
}
} }
} else { dst_release(&rt->u.dst);
no_link:
dev->iflink = 0;
dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
} }
} }
...@@ -995,7 +950,7 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -995,7 +950,7 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
switch (cmd) { switch (cmd) {
case SIOCGETTUNNEL: case SIOCGETTUNNEL:
if (dev == &ip6ip6_fb_tnl_dev) { if (dev == ip6ip6_fb_tnl_dev) {
if (copy_from_user(&p, if (copy_from_user(&p,
ifr->ifr_ifru.ifru_data, ifr->ifr_ifru.ifru_data,
sizeof (p))) { sizeof (p))) {
...@@ -1024,7 +979,7 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -1024,7 +979,7 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
err = -EFAULT; err = -EFAULT;
break; break;
} }
if (!create && dev != &ip6ip6_fb_tnl_dev) { if (!create && dev != ip6ip6_fb_tnl_dev) {
t = (struct ip6_tnl *) dev->priv; t = (struct ip6_tnl *) dev->priv;
} }
if (!t && (err = ip6ip6_tnl_locate(&p, &t, create))) { if (!t && (err = ip6ip6_tnl_locate(&p, &t, create))) {
...@@ -1052,7 +1007,7 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -1052,7 +1007,7 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
break; break;
if (dev == &ip6ip6_fb_tnl_dev) { if (dev == ip6ip6_fb_tnl_dev) {
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, if (copy_from_user(&p, ifr->ifr_ifru.ifru_data,
sizeof (p))) { sizeof (p))) {
err = -EFAULT; err = -EFAULT;
...@@ -1061,14 +1016,14 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -1061,14 +1016,14 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
err = ip6ip6_tnl_locate(&p, &t, 0); err = ip6ip6_tnl_locate(&p, &t, 0);
if (err) if (err)
break; break;
if (t == &ip6ip6_fb_tnl) { if (t == ip6ip6_fb_tnl_dev->priv) {
err = -EPERM; err = -EPERM;
break; break;
} }
} else { } else {
t = (struct ip6_tnl *) dev->priv; t = (struct ip6_tnl *) dev->priv;
} }
err = ip6_tnl_destroy(t); err = unregister_netdevice(t->dev);
break; break;
default: default:
err = -EINVAL; err = -EINVAL;
...@@ -1110,40 +1065,49 @@ ip6ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) ...@@ -1110,40 +1065,49 @@ ip6ip6_tnl_change_mtu(struct net_device *dev, int new_mtu)
} }
/** /**
* ip6ip6_tnl_dev_init_gen - general initializer for all tunnel devices * ip6ip6_tnl_dev_setup - setup virtual tunnel device
* @dev: virtual device associated with tunnel * @dev: virtual device associated with tunnel
* *
* Description: * Description:
* Set function pointers and initialize the &struct flowi template used * Initialize function pointers and device parameters
* by the tunnel.
**/ **/
static void static void ip6ip6_tnl_dev_setup(struct net_device *dev)
ip6ip6_tnl_dev_init_gen(struct net_device *dev)
{ {
struct ip6_tnl *t = (struct ip6_tnl *) dev->priv; SET_MODULE_OWNER(dev);
struct flowi *fl = &t->fl;
memset(fl, 0, sizeof (*fl));
fl->proto = IPPROTO_IPV6;
dev->destructor = ip6ip6_tnl_dev_destructor;
dev->uninit = ip6ip6_tnl_dev_uninit; dev->uninit = ip6ip6_tnl_dev_uninit;
dev->destructor = (void (*)(struct net_device *))kfree;
dev->hard_start_xmit = ip6ip6_tnl_xmit; dev->hard_start_xmit = ip6ip6_tnl_xmit;
dev->get_stats = ip6ip6_tnl_get_stats; dev->get_stats = ip6ip6_tnl_get_stats;
dev->do_ioctl = ip6ip6_tnl_ioctl; dev->do_ioctl = ip6ip6_tnl_ioctl;
dev->change_mtu = ip6ip6_tnl_change_mtu; dev->change_mtu = ip6ip6_tnl_change_mtu;
dev->type = ARPHRD_TUNNEL6; dev->type = ARPHRD_TUNNEL6;
dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
dev->flags |= IFF_NOARP; dev->flags |= IFF_NOARP;
if (ipv6_addr_type(&t->parms.raddr) & IPV6_ADDR_UNICAST && dev->iflink = 0;
ipv6_addr_type(&t->parms.laddr) & IPV6_ADDR_UNICAST)
dev->flags |= IFF_POINTOPOINT;
/* Hmm... MAX_ADDR_LEN is 8, so the ipv6 addresses can't be /* Hmm... MAX_ADDR_LEN is 8, so the ipv6 addresses can't be
copied to dev->dev_addr and dev->broadcast, like the ipv4 copied to dev->dev_addr and dev->broadcast, like the ipv4
addresses were in ipip.c, ip_gre.c and sit.c. */ addresses were in ipip.c, ip_gre.c and sit.c. */
dev->addr_len = 0; dev->addr_len = 0;
} }
/**
* ip6ip6_tnl_dev_init_gen - general initializer for all tunnel devices
* @dev: virtual device associated with tunnel
**/
static inline void
ip6ip6_tnl_dev_init_gen(struct net_device *dev)
{
struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
t->fl.proto = IPPROTO_IPV6;
t->dev = dev;
strcpy(t->parms.name, dev->name);
}
/** /**
* ip6ip6_tnl_dev_init - initializer for all non fallback tunnel devices * ip6ip6_tnl_dev_init - initializer for all non fallback tunnel devices
* @dev: virtual device associated with tunnel * @dev: virtual device associated with tunnel
...@@ -1167,8 +1131,10 @@ ip6ip6_tnl_dev_init(struct net_device *dev) ...@@ -1167,8 +1131,10 @@ ip6ip6_tnl_dev_init(struct net_device *dev)
int ip6ip6_fb_tnl_dev_init(struct net_device *dev) int ip6ip6_fb_tnl_dev_init(struct net_device *dev)
{ {
struct ip6_tnl *t = dev->priv;
ip6ip6_tnl_dev_init_gen(dev); ip6ip6_tnl_dev_init_gen(dev);
tnls_wc[0] = &ip6ip6_fb_tnl; dev_hold(dev);
tnls_wc[0] = t;
return 0; return 0;
} }
...@@ -1190,8 +1156,6 @@ int __init ip6_tunnel_init(void) ...@@ -1190,8 +1156,6 @@ int __init ip6_tunnel_init(void)
struct sock *sk; struct sock *sk;
struct ipv6_pinfo *np; struct ipv6_pinfo *np;
ip6ip6_fb_tnl_dev.priv = (void *) &ip6ip6_fb_tnl;
for (i = 0; i < NR_CPUS; i++) { for (i = 0; i < NR_CPUS; i++) {
if (!cpu_possible(i)) if (!cpu_possible(i))
continue; continue;
...@@ -1219,10 +1183,23 @@ int __init ip6_tunnel_init(void) ...@@ -1219,10 +1183,23 @@ int __init ip6_tunnel_init(void)
goto fail; goto fail;
} }
SET_MODULE_OWNER(&ip6ip6_fb_tnl_dev);
register_netdev(&ip6ip6_fb_tnl_dev);
ip6ip6_fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
ip6ip6_tnl_dev_setup);
if (!ip6ip6_fb_tnl_dev) {
err = -ENOMEM;
goto tnl_fail;
}
ip6ip6_fb_tnl_dev->init = ip6ip6_fb_tnl_dev_init;
if ((err = register_netdev(ip6ip6_fb_tnl_dev))) {
kfree(ip6ip6_fb_tnl_dev);
goto tnl_fail;
}
return 0; return 0;
tnl_fail:
inet6_del_protocol(&ip6ip6_protocol, IPPROTO_IPV6);
fail: fail:
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
if (!cpu_possible(j)) if (!cpu_possible(j))
...@@ -1241,7 +1218,7 @@ void ip6_tunnel_cleanup(void) ...@@ -1241,7 +1218,7 @@ void ip6_tunnel_cleanup(void)
{ {
int i; int i;
unregister_netdev(&ip6ip6_fb_tnl_dev); unregister_netdev(ip6ip6_fb_tnl_dev);
inet6_del_protocol(&ip6ip6_protocol, IPPROTO_IPV6); inet6_del_protocol(&ip6ip6_protocol, IPPROTO_IPV6);
......
...@@ -743,7 +743,10 @@ static int ipip6_tunnel_init(struct net_device *dev) ...@@ -743,7 +743,10 @@ static int ipip6_tunnel_init(struct net_device *dev)
tunnel = (struct ip_tunnel*)dev->priv; tunnel = (struct ip_tunnel*)dev->priv;
iph = &tunnel->parms.iph; iph = &tunnel->parms.iph;
tunnel->dev = dev; tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
...@@ -780,6 +783,9 @@ int __init ipip6_fb_tunnel_init(struct net_device *dev) ...@@ -780,6 +783,9 @@ int __init ipip6_fb_tunnel_init(struct net_device *dev)
struct ip_tunnel *tunnel = dev->priv; struct ip_tunnel *tunnel = dev->priv;
struct iphdr *iph = &tunnel->parms.iph; struct iphdr *iph = &tunnel->parms.iph;
tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
iph->version = 4; iph->version = 4;
iph->protocol = IPPROTO_IPV6; iph->protocol = IPPROTO_IPV6;
iph->ihl = 5; iph->ihl = 5;
......
...@@ -544,7 +544,6 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, ...@@ -544,7 +544,6 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct tcp_opt *tp = tcp_sk(sk); struct tcp_opt *tp = tcp_sk(sk);
struct in6_addr *saddr = NULL; struct in6_addr *saddr = NULL;
struct in6_addr saddr_buf;
struct flowi fl; struct flowi fl;
struct dst_entry *dst; struct dst_entry *dst;
int addr_type; int addr_type;
...@@ -671,23 +670,24 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, ...@@ -671,23 +670,24 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
goto failure; goto failure;
} }
ip6_dst_store(sk, dst, NULL);
sk->sk_route_caps = dst->dev->features &
~(NETIF_F_IP_CSUM | NETIF_F_TSO);
if (saddr == NULL) { if (saddr == NULL) {
err = ipv6_get_saddr(dst, &np->daddr, &saddr_buf); err = ipv6_get_saddr(dst, &np->daddr, &fl.fl6_src);
if (err) if (err) {
dst_release(dst);
goto failure; goto failure;
}
saddr = &saddr_buf; saddr = &fl.fl6_src;
ipv6_addr_copy(&np->rcv_saddr, saddr);
} }
/* set the source address */ /* set the source address */
ipv6_addr_copy(&np->rcv_saddr, saddr);
ipv6_addr_copy(&np->saddr, saddr); ipv6_addr_copy(&np->saddr, saddr);
inet->rcv_saddr = LOOPBACK4_IPV6; inet->rcv_saddr = LOOPBACK4_IPV6;
ip6_dst_store(sk, dst, NULL);
sk->sk_route_caps = dst->dev->features &
~(NETIF_F_IP_CSUM | NETIF_F_TSO);
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;
...@@ -714,8 +714,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, ...@@ -714,8 +714,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
late_failure: late_failure:
tcp_set_state(sk, TCP_CLOSE); tcp_set_state(sk, TCP_CLOSE);
failure:
__sk_dst_reset(sk); __sk_dst_reset(sk);
failure:
inet->dport = 0; inet->dport = 0;
sk->sk_route_caps = 0; sk->sk_route_caps = 0;
return err; return err;
......
...@@ -1614,7 +1614,7 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) ...@@ -1614,7 +1614,7 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
goto out; goto out;
/* do not move before msg_sys is valid */ /* do not move before msg_sys is valid */
err = -EINVAL; err = -EMSGSIZE;
if (msg_sys.msg_iovlen > UIO_MAXIOV) if (msg_sys.msg_iovlen > UIO_MAXIOV)
goto out_put; goto out_put;
...@@ -1713,7 +1713,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flag ...@@ -1713,7 +1713,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flag
if (!sock) if (!sock)
goto out; goto out;
err = -EINVAL; err = -EMSGSIZE;
if (msg_sys.msg_iovlen > UIO_MAXIOV) if (msg_sys.msg_iovlen > UIO_MAXIOV)
goto out_put; goto out_put;
......
...@@ -922,6 +922,8 @@ EXPORT_SYMBOL(wanrouter_type_trans); ...@@ -922,6 +922,8 @@ EXPORT_SYMBOL(wanrouter_type_trans);
EXPORT_SYMBOL(lock_adapter_irq); EXPORT_SYMBOL(lock_adapter_irq);
EXPORT_SYMBOL(unlock_adapter_irq); EXPORT_SYMBOL(unlock_adapter_irq);
MODULE_LICENSE("GPL");
/* /*
* End * End
*/ */
...@@ -790,9 +790,11 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, ...@@ -790,9 +790,11 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
goto error; goto error;
} }
if (err == -EAGAIN || if (err == -EAGAIN ||
genid != atomic_read(&flow_cache_genid)) genid != atomic_read(&flow_cache_genid)) {
xfrm_pol_put(policy);
goto restart; goto restart;
} }
}
if (err) if (err)
goto error; goto error;
} else if (nx == 0) { } else if (nx == 0) {
......
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