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)
if (ns == 0)
goto outf;
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);
skb = ns;
}
......@@ -1455,7 +1455,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
goto err;
}
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);
skb = ns;
}
......@@ -1826,7 +1826,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
if (head != tail)
/* copy to a single skb */
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;
head = tail->next;
}
......
......@@ -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_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. */
HMD(("rseed/macaddr, "));
......
......@@ -276,8 +276,10 @@ static inline void ipv6_addr_prefix(struct in6_addr *pfx,
b = plen & 0x7;
memcpy(pfx->s6_addr, addr, o);
if (b != 0)
if (b != 0) {
pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b);
o++;
}
if (o < 16)
memset(pfx->s6_addr + o, 0, 16 - o);
}
......
......@@ -628,13 +628,6 @@ static inline void tcp_openreq_free(struct open_request *req)
/*
* Pointers to address related TCP functions
* (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 {
......
......@@ -1154,6 +1154,8 @@ static int ipgre_tunnel_init(struct net_device *dev)
iph = &tunnel->parms.iph;
tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
......@@ -1215,6 +1217,9 @@ int __init ipgre_fb_tunnel_init(struct net_device *dev)
struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
struct iphdr *iph = &tunnel->parms.iph;
tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
iph->version = 4;
iph->protocol = IPPROTO_GRE;
iph->ihl = 5;
......
......@@ -805,7 +805,10 @@ static int ipip_tunnel_init(struct net_device *dev)
tunnel = (struct ip_tunnel*)dev->priv;
iph = &tunnel->parms.iph;
tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
......@@ -841,6 +844,9 @@ static int __init ipip_fb_tunnel_init(struct net_device *dev)
struct ip_tunnel *tunnel = dev->priv;
struct iphdr *iph = &tunnel->parms.iph;
tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
iph->version = 4;
iph->protocol = IPPROTO_IPIP;
iph->ihl = 5;
......
......@@ -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_initialize_rcv_mss(sk);
/* Make sure socket is routed, for correct metrics. */
tp->af_specific->rebuild_header(sk);
tcp_init_metrics(sk);
/* Prevent spurious tcp_cwnd_restart() on first data
* packet.
*/
tp->lsndtime = tcp_time_stamp;
tcp_init_buffer_space(sk);
if (sock_flag(sk, SOCK_KEEPOPEN))
......@@ -3959,7 +3969,18 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
if (tp->tstamp_ok)
tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
/* Make sure socket is routed, for
* correct metrics.
*/
tp->af_specific->rebuild_header(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_init_buffer_space(sk);
tcp_fast_path_on(tp);
......
......@@ -87,18 +87,11 @@ static void ip6_xmit_unlock(void)
static int ip6ip6_fb_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 */
static struct net_device ip6ip6_fb_tnl_dev = {
.name = "ip6tnl0",
.init = ip6ip6_fb_tnl_dev_init
};
static struct net_device *ip6ip6_fb_tnl_dev;
/* 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 */
static struct ip6_tnl *tnls_r_l[HASH_SIZE];
......@@ -216,59 +209,39 @@ static int
ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt)
{
struct net_device *dev;
int err = -ENOBUFS;
struct ip6_tnl *t;
char name[IFNAMSIZ];
int err;
dev = kmalloc(sizeof (*dev) + sizeof (*t), GFP_KERNEL);
if (!dev)
return err;
if (p->name[0]) {
strlcpy(name, p->name, IFNAMSIZ);
} 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));
dev->priv = (void *) (dev + 1);
t = (struct ip6_tnl *) dev->priv;
t->dev = dev;
t = dev->priv;
dev->init = ip6ip6_tnl_dev_init;
memcpy(&t->parms, p, sizeof (*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);
t->parms = *p;
if (i == IP6_TNL_MAX) {
goto failed;
}
memcpy(t->parms.name, dev->name, IFNAMSIZ);
}
SET_MODULE_OWNER(dev);
if ((err = register_netdevice(dev)) < 0) {
goto failed;
kfree(dev);
return err;
}
dev_hold(dev);
ip6ip6_tnl_link(t);
*pt = t;
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)
return (create ? -EEXIST : 0);
}
}
if (!create) {
if (!create)
return -ENODEV;
}
return ip6_tnl_create(p, pt);
}
/**
* ip6ip6_tnl_dev_destructor - tunnel device destructor
* @dev: the device to be destroyed
**/
static void
ip6ip6_tnl_dev_destructor(struct net_device *dev)
{
kfree(dev);
return ip6_tnl_create(p, pt);
}
/**
......@@ -332,14 +294,14 @@ ip6ip6_tnl_dev_destructor(struct net_device *dev)
static void
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);
tnls_wc[0] = NULL;
write_unlock_bh(&ip6ip6_lock);
} else {
struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
ip6ip6_tnl_unlink(t);
ip6ip6_tnl_unlink((struct ip6_tnl *) dev->priv);
}
dev_put(dev);
}
/**
......@@ -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);
if (rt)
dst_free(&rt->u.dst);
dst_release(&rt->u.dst);
kfree_skb(skb2);
}
......@@ -878,7 +840,6 @@ static void ip6_tnl_set_cap(struct ip6_tnl *t)
}
}
static void ip6ip6_tnl_link_config(struct ip6_tnl *t)
{
struct net_device *dev = t->dev;
......@@ -906,31 +867,25 @@ static void ip6ip6_tnl_link_config(struct ip6_tnl *t)
if (p->flags & IP6_TNL_F_CAP_XMIT) {
struct rt6_info *rt = rt6_lookup(&p->raddr, &p->laddr,
p->link, 0);
if (rt) {
struct net_device *rtdev;
if (!(rtdev = rt->rt6i_dev) ||
rtdev->type == ARPHRD_TUNNEL6) {
/* as long as tunnels use the same socket
for transmission, locally nested tunnels
won't work */
dst_release(&rt->u.dst);
goto no_link;
} else {
dev->iflink = rtdev->ifindex;
dev->hard_header_len = rtdev->hard_header_len +
if (rt == NULL)
return;
/* as long as tunnels use the same socket for transmission,
locally nested tunnels won't work */
if (rt->rt6i_dev && rt->rt6i_dev->type != ARPHRD_TUNNEL6) {
dev->iflink = rt->rt6i_dev->ifindex;
dev->hard_header_len = rt->rt6i_dev->hard_header_len +
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)
dev->mtu = IPV6_MIN_MTU;
dst_release(&rt->u.dst);
}
}
} else {
no_link:
dev->iflink = 0;
dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
dst_release(&rt->u.dst);
}
}
......@@ -995,7 +950,7 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
switch (cmd) {
case SIOCGETTUNNEL:
if (dev == &ip6ip6_fb_tnl_dev) {
if (dev == ip6ip6_fb_tnl_dev) {
if (copy_from_user(&p,
ifr->ifr_ifru.ifru_data,
sizeof (p))) {
......@@ -1024,7 +979,7 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
err = -EFAULT;
break;
}
if (!create && dev != &ip6ip6_fb_tnl_dev) {
if (!create && dev != ip6ip6_fb_tnl_dev) {
t = (struct ip6_tnl *) dev->priv;
}
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)
if (!capable(CAP_NET_ADMIN))
break;
if (dev == &ip6ip6_fb_tnl_dev) {
if (dev == ip6ip6_fb_tnl_dev) {
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data,
sizeof (p))) {
err = -EFAULT;
......@@ -1061,14 +1016,14 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
err = ip6ip6_tnl_locate(&p, &t, 0);
if (err)
break;
if (t == &ip6ip6_fb_tnl) {
if (t == ip6ip6_fb_tnl_dev->priv) {
err = -EPERM;
break;
}
} else {
t = (struct ip6_tnl *) dev->priv;
}
err = ip6_tnl_destroy(t);
err = unregister_netdevice(t->dev);
break;
default:
err = -EINVAL;
......@@ -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
*
* Description:
* Set function pointers and initialize the &struct flowi template used
* by the tunnel.
* Initialize function pointers and device parameters
**/
static void
ip6ip6_tnl_dev_init_gen(struct net_device *dev)
static void ip6ip6_tnl_dev_setup(struct net_device *dev)
{
struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
struct flowi *fl = &t->fl;
memset(fl, 0, sizeof (*fl));
fl->proto = IPPROTO_IPV6;
dev->destructor = ip6ip6_tnl_dev_destructor;
SET_MODULE_OWNER(dev);
dev->uninit = ip6ip6_tnl_dev_uninit;
dev->destructor = (void (*)(struct net_device *))kfree;
dev->hard_start_xmit = ip6ip6_tnl_xmit;
dev->get_stats = ip6ip6_tnl_get_stats;
dev->do_ioctl = ip6ip6_tnl_ioctl;
dev->change_mtu = ip6ip6_tnl_change_mtu;
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;
if (ipv6_addr_type(&t->parms.raddr) & IPV6_ADDR_UNICAST &&
ipv6_addr_type(&t->parms.laddr) & IPV6_ADDR_UNICAST)
dev->flags |= IFF_POINTOPOINT;
dev->iflink = 0;
/* Hmm... MAX_ADDR_LEN is 8, so the ipv6 addresses can't be
copied to dev->dev_addr and dev->broadcast, like the ipv4
addresses were in ipip.c, ip_gre.c and sit.c. */
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
* @dev: virtual device associated with tunnel
......@@ -1167,8 +1131,10 @@ ip6ip6_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);
tnls_wc[0] = &ip6ip6_fb_tnl;
dev_hold(dev);
tnls_wc[0] = t;
return 0;
}
......@@ -1190,8 +1156,6 @@ int __init ip6_tunnel_init(void)
struct sock *sk;
struct ipv6_pinfo *np;
ip6ip6_fb_tnl_dev.priv = (void *) &ip6ip6_fb_tnl;
for (i = 0; i < NR_CPUS; i++) {
if (!cpu_possible(i))
continue;
......@@ -1219,10 +1183,23 @@ int __init ip6_tunnel_init(void)
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;
tnl_fail:
inet6_del_protocol(&ip6ip6_protocol, IPPROTO_IPV6);
fail:
for (j = 0; j < i; j++) {
if (!cpu_possible(j))
......@@ -1241,7 +1218,7 @@ void ip6_tunnel_cleanup(void)
{
int i;
unregister_netdev(&ip6ip6_fb_tnl_dev);
unregister_netdev(ip6ip6_fb_tnl_dev);
inet6_del_protocol(&ip6ip6_protocol, IPPROTO_IPV6);
......
......@@ -743,7 +743,10 @@ static int ipip6_tunnel_init(struct net_device *dev)
tunnel = (struct ip_tunnel*)dev->priv;
iph = &tunnel->parms.iph;
tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
......@@ -780,6 +783,9 @@ int __init ipip6_fb_tunnel_init(struct net_device *dev)
struct ip_tunnel *tunnel = dev->priv;
struct iphdr *iph = &tunnel->parms.iph;
tunnel->dev = dev;
strcpy(tunnel->parms.name, dev->name);
iph->version = 4;
iph->protocol = IPPROTO_IPV6;
iph->ihl = 5;
......
......@@ -544,7 +544,6 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
struct ipv6_pinfo *np = inet6_sk(sk);
struct tcp_opt *tp = tcp_sk(sk);
struct in6_addr *saddr = NULL;
struct in6_addr saddr_buf;
struct flowi fl;
struct dst_entry *dst;
int addr_type;
......@@ -671,23 +670,24 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
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) {
err = ipv6_get_saddr(dst, &np->daddr, &saddr_buf);
if (err)
err = ipv6_get_saddr(dst, &np->daddr, &fl.fl6_src);
if (err) {
dst_release(dst);
goto failure;
saddr = &saddr_buf;
}
saddr = &fl.fl6_src;
ipv6_addr_copy(&np->rcv_saddr, saddr);
}
/* set the source address */
ipv6_addr_copy(&np->rcv_saddr, saddr);
ipv6_addr_copy(&np->saddr, saddr);
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;
if (np->opt)
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,
late_failure:
tcp_set_state(sk, TCP_CLOSE);
failure:
__sk_dst_reset(sk);
failure:
inet->dport = 0;
sk->sk_route_caps = 0;
return err;
......
......@@ -1614,7 +1614,7 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
goto out;
/* do not move before msg_sys is valid */
err = -EINVAL;
err = -EMSGSIZE;
if (msg_sys.msg_iovlen > UIO_MAXIOV)
goto out_put;
......@@ -1713,7 +1713,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flag
if (!sock)
goto out;
err = -EINVAL;
err = -EMSGSIZE;
if (msg_sys.msg_iovlen > UIO_MAXIOV)
goto out_put;
......
......@@ -922,6 +922,8 @@ EXPORT_SYMBOL(wanrouter_type_trans);
EXPORT_SYMBOL(lock_adapter_irq);
EXPORT_SYMBOL(unlock_adapter_irq);
MODULE_LICENSE("GPL");
/*
* End
*/
......@@ -790,9 +790,11 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
goto error;
}
if (err == -EAGAIN ||
genid != atomic_read(&flow_cache_genid))
genid != atomic_read(&flow_cache_genid)) {
xfrm_pol_put(policy);
goto restart;
}
}
if (err)
goto error;
} 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