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

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

into nuts.ninka.net:/disk1/davem/BK/net-2.5
parents 80d63a94 20b58805
...@@ -3,12 +3,12 @@ of the IrDA Utilities. More detailed information about these and associated ...@@ -3,12 +3,12 @@ of the IrDA Utilities. More detailed information about these and associated
programs can be found on http://irda.sourceforge.net/ programs can be found on http://irda.sourceforge.net/
For more information about how to use the IrDA protocol stack, see the For more information about how to use the IrDA protocol stack, see the
IR-HOWTO (http://www.mobilix.org/Infrared-HOWTO/Infrared-HOWTO.html) written by Werner Heuser Linux Infared HOWTO (http://www.tuxmobil.org/Infrared-HOWTO/Infrared-HOWTO.html)
<wehe@mobilix.org> by Werner Heuser <wehe@tuxmobil.org>
There is an active mailing list for discussing Linux-IrDA matters called There is an active mailing list for discussing Linux-IrDA matters called
linux-irda. To subscribe to it, visit: irda-users@lists.sourceforge.net
http://www.pasta.cs.uit.no/mailman/listinfo/linux-irda
Dag Brattli <dagb@cs.uit.no>
...@@ -140,29 +140,29 @@ struct ip_msfilter { ...@@ -140,29 +140,29 @@ struct ip_msfilter {
struct group_req struct group_req
{ {
__u32 gr_interface; /* interface index */ __u32 gr_interface; /* interface index */
struct sockaddr_storage gr_group; /* group address */ struct __kernel_sockaddr_storage gr_group; /* group address */
}; };
struct group_source_req struct group_source_req
{ {
__u32 gsr_interface; /* interface index */ __u32 gsr_interface; /* interface index */
struct sockaddr_storage gsr_group; /* group address */ struct __kernel_sockaddr_storage gsr_group; /* group address */
struct sockaddr_storage gsr_source; /* source address */ struct __kernel_sockaddr_storage gsr_source; /* source address */
}; };
struct group_filter struct group_filter
{ {
__u32 gf_interface; /* interface index */ __u32 gf_interface; /* interface index */
struct sockaddr_storage gf_group; /* multicast address */ struct __kernel_sockaddr_storage gf_group; /* multicast address */
__u32 gf_fmode; /* filter mode */ __u32 gf_fmode; /* filter mode */
__u32 gf_numsrc; /* number of sources */ __u32 gf_numsrc; /* number of sources */
struct sockaddr_storage gf_slist[1]; /* interface index */ struct __kernel_sockaddr_storage gf_slist[1]; /* interface index */
}; };
#define GROUP_FILTER_SIZE(numsrc) \ #define GROUP_FILTER_SIZE(numsrc) \
(sizeof(struct group_filter) - sizeof(struct sockaddr_storage) \ (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \
+ (numsrc) * sizeof(struct sockaddr_storage)) + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
struct in_pktinfo struct in_pktinfo
{ {
......
#ifndef _LINUX_SOCKET_H #ifndef _LINUX_SOCKET_H
#define _LINUX_SOCKET_H #define _LINUX_SOCKET_H
/*
* Desired design of maximum size and alignment (see RFC2553)
*/
#define _K_SS_MAXSIZE 128 /* Implementation specific max size */
#define _K_SS_ALIGNSIZE (__alignof__ (struct sockaddr *))
/* Implementation specific desired alignment */
struct __kernel_sockaddr_storage {
unsigned short ss_family; /* address family */
/* Following field(s) are implementation specific */
char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
/* space to achieve desired size, */
/* _SS_MAXSIZE value minus size of ss_family */
} __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */
#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
#include <linux/config.h> /* for CONFIG_COMPAT */ #include <linux/config.h> /* for CONFIG_COMPAT */
...@@ -27,20 +42,7 @@ struct linger { ...@@ -27,20 +42,7 @@ struct linger {
int l_linger; /* How long to linger for */ int l_linger; /* How long to linger for */
}; };
/* #define sockaddr_storage __kernel_sockaddr_storage
* Desired design of maximum size and alignment (see RFC2553)
*/
#define _SS_MAXSIZE 128 /* Implementation specific max size */
#define _SS_ALIGNSIZE (__alignof__ (struct sockaddr *))
/* Implementation specific desired alignment */
struct sockaddr_storage {
sa_family_t ss_family; /* address family */
/* Following field(s) are implementation specific */
char __data[_SS_MAXSIZE - sizeof(sa_family_t)];
/* space to achieve desired size, */
/* _SS_MAXSIZE value minus size of ss_family */
} __attribute__ ((aligned(_SS_ALIGNSIZE))); /* force desired alignment */
/* /*
* As we do 4.4BSD message passing we use a 4.4BSD message passing * As we do 4.4BSD message passing we use a 4.4BSD message passing
......
...@@ -154,8 +154,14 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) ...@@ -154,8 +154,14 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
static void sock_warn_obsolete_bsdism(const char *name) static void sock_warn_obsolete_bsdism(const char *name)
{ {
printk(KERN_WARNING "process `%s' is using obsolete " static int warned;
"%s SO_BSDCOMPAT\n", current->comm, name); static char warncomm[16];
if (strcmp(warncomm, current->comm) && warned < 5) {
strcpy(warncomm, current->comm);
printk(KERN_WARNING "process `%s' is using obsolete "
"%s SO_BSDCOMPAT\n", warncomm, name);
warned++;
}
} }
/* /*
......
...@@ -1124,18 +1124,16 @@ static inline int ipmr_forward_finish(struct sk_buff *skb) ...@@ -1124,18 +1124,16 @@ static inline int ipmr_forward_finish(struct sk_buff *skb)
* Processing handlers for ipmr_forward * Processing handlers for ipmr_forward
*/ */
static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi);
int vifi, int last)
{ {
struct iphdr *iph = skb->nh.iph; struct iphdr *iph = skb->nh.iph;
struct vif_device *vif = &vif_table[vifi]; struct vif_device *vif = &vif_table[vifi];
struct net_device *dev; struct net_device *dev;
struct rtable *rt; struct rtable *rt;
int encap = 0; int encap = 0;
struct sk_buff *skb2;
if (vif->dev == NULL) if (vif->dev == NULL)
return; goto out_free;
#ifdef CONFIG_IP_PIMSM #ifdef CONFIG_IP_PIMSM
if (vif->flags & VIFF_REGISTER) { if (vif->flags & VIFF_REGISTER) {
...@@ -1144,6 +1142,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, ...@@ -1144,6 +1142,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
((struct net_device_stats*)vif->dev->priv)->tx_bytes += skb->len; ((struct net_device_stats*)vif->dev->priv)->tx_bytes += skb->len;
((struct net_device_stats*)vif->dev->priv)->tx_packets++; ((struct net_device_stats*)vif->dev->priv)->tx_packets++;
ipmr_cache_report(skb, vifi, IGMPMSG_WHOLEPKT); ipmr_cache_report(skb, vifi, IGMPMSG_WHOLEPKT);
kfree_skb(skb);
return; return;
} }
#endif #endif
...@@ -1156,7 +1155,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, ...@@ -1156,7 +1155,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
.tos = RT_TOS(iph->tos) } }, .tos = RT_TOS(iph->tos) } },
.proto = IPPROTO_IPIP }; .proto = IPPROTO_IPIP };
if (ip_route_output_key(&rt, &fl)) if (ip_route_output_key(&rt, &fl))
return; goto out_free;
encap = sizeof(struct iphdr); encap = sizeof(struct iphdr);
} else { } else {
struct flowi fl = { .oif = vif->link, struct flowi fl = { .oif = vif->link,
...@@ -1165,7 +1164,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, ...@@ -1165,7 +1164,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
.tos = RT_TOS(iph->tos) } }, .tos = RT_TOS(iph->tos) } },
.proto = IPPROTO_IPIP }; .proto = IPPROTO_IPIP };
if (ip_route_output_key(&rt, &fl)) if (ip_route_output_key(&rt, &fl))
return; goto out_free;
} }
dev = rt->u.dst.dev; dev = rt->u.dst.dev;
...@@ -1178,43 +1177,34 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, ...@@ -1178,43 +1177,34 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
IP_INC_STATS_BH(IpFragFails); IP_INC_STATS_BH(IpFragFails);
ip_rt_put(rt); ip_rt_put(rt);
return; goto out_free;
} }
encap += LL_RESERVED_SPACE(dev); encap += LL_RESERVED_SPACE(dev) + rt->u.dst.header_len;
if (skb_headroom(skb) < encap || skb_cloned(skb) || !last)
skb2 = skb_realloc_headroom(skb, (encap + 15)&~15);
else if (atomic_read(&skb->users) != 1)
skb2 = skb_clone(skb, GFP_ATOMIC);
else {
atomic_inc(&skb->users);
skb2 = skb;
}
if (skb2 == NULL) { if (skb_cow(skb, encap)) {
ip_rt_put(rt); ip_rt_put(rt);
return; goto out_free;
} }
vif->pkt_out++; vif->pkt_out++;
vif->bytes_out+=skb->len; vif->bytes_out+=skb->len;
dst_release(skb2->dst); dst_release(skb->dst);
skb2->dst = &rt->u.dst; skb->dst = &rt->u.dst;
iph = skb2->nh.iph; iph = skb->nh.iph;
ip_decrease_ttl(iph); ip_decrease_ttl(iph);
/* FIXME: forward and output firewalls used to be called here. /* FIXME: forward and output firewalls used to be called here.
* What do we do with netfilter? -- RR */ * What do we do with netfilter? -- RR */
if (vif->flags & VIFF_TUNNEL) { if (vif->flags & VIFF_TUNNEL) {
ip_encap(skb2, vif->local, vif->remote); ip_encap(skb, vif->local, vif->remote);
/* FIXME: extra output firewall step used to be here. --RR */ /* FIXME: extra output firewall step used to be here. --RR */
((struct ip_tunnel *)vif->dev->priv)->stat.tx_packets++; ((struct ip_tunnel *)vif->dev->priv)->stat.tx_packets++;
((struct ip_tunnel *)vif->dev->priv)->stat.tx_bytes+=skb2->len; ((struct ip_tunnel *)vif->dev->priv)->stat.tx_bytes+=skb->len;
} }
IPCB(skb2)->flags |= IPSKB_FORWARDED; IPCB(skb)->flags |= IPSKB_FORWARDED;
/* /*
* RFC1584 teaches, that DVMRP/PIM router must deliver packets locally * RFC1584 teaches, that DVMRP/PIM router must deliver packets locally
...@@ -1227,8 +1217,13 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, ...@@ -1227,8 +1217,13 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
* not mrouter) cannot join to more than one interface - it will * not mrouter) cannot join to more than one interface - it will
* result in receiving multiple packets. * result in receiving multiple packets.
*/ */
NF_HOOK(PF_INET, NF_IP_FORWARD, skb2, skb->dev, dev, NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, dev,
ipmr_forward_finish); ipmr_forward_finish);
return;
out_free:
kfree_skb(skb);
return;
} }
static int ipmr_find_vif(struct net_device *dev) static int ipmr_find_vif(struct net_device *dev)
...@@ -1299,13 +1294,24 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local ...@@ -1299,13 +1294,24 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local
*/ */
for (ct = cache->mfc_un.res.maxvif-1; ct >= cache->mfc_un.res.minvif; ct--) { for (ct = cache->mfc_un.res.maxvif-1; ct >= cache->mfc_un.res.minvif; ct--) {
if (skb->nh.iph->ttl > cache->mfc_un.res.ttls[ct]) { if (skb->nh.iph->ttl > cache->mfc_un.res.ttls[ct]) {
if (psend != -1) if (psend != -1) {
ipmr_queue_xmit(skb, cache, psend, 0); struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
if (skb2)
ipmr_queue_xmit(skb2, cache, psend);
}
psend=ct; psend=ct;
} }
} }
if (psend != -1) if (psend != -1) {
ipmr_queue_xmit(skb, cache, psend, !local); if (local) {
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
if (skb2)
ipmr_queue_xmit(skb2, cache, psend);
} else {
ipmr_queue_xmit(skb, cache, psend);
return 0;
}
}
dont_forward: dont_forward:
if (!local) if (!local)
......
...@@ -1465,15 +1465,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) ...@@ -1465,15 +1465,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
tp.saw_tstamp = 0; tp.saw_tstamp = 0;
} }
if (tp.saw_tstamp && !tp.rcv_tsval) {
/* Some OSes (unknown ones, but I see them on web server, which
* contains information interesting only for windows'
* users) do not send their stamp in SYN. It is easy case.
* We simply do not advertise TS support.
*/
tp.saw_tstamp = 0;
tp.tstamp_ok = 0;
}
tp.tstamp_ok = tp.saw_tstamp; tp.tstamp_ok = tp.saw_tstamp;
tcp_openreq_init(req, &tp, skb); tcp_openreq_init(req, &tp, skb);
......
...@@ -169,7 +169,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int ...@@ -169,7 +169,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
dst_prev->output = dst_prev->xfrm->type->output; dst_prev->output = dst_prev->xfrm->type->output;
/* Sheit... I remember I did this right. Apparently, /* Sheit... I remember I did this right. Apparently,
* it was magically lost, so this code needs audit */ * it was magically lost, so this code needs audit */
x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL); x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL|RTF_NDISC);
x->u.rt6.rt6i_metric = rt0->rt6i_metric; x->u.rt6.rt6i_metric = rt0->rt6i_metric;
x->u.rt6.rt6i_node = rt0->rt6i_node; x->u.rt6.rt6i_node = rt0->rt6i_node;
x->u.rt6.rt6i_gateway = rt0->rt6i_gateway; x->u.rt6.rt6i_gateway = rt0->rt6i_gateway;
......
...@@ -853,6 +853,8 @@ static inline int ...@@ -853,6 +853,8 @@ static inline int
xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x, xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x,
unsigned short family) unsigned short family)
{ {
if (xfrm_state_kern(x))
return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, family);
return x->id.proto == tmpl->id.proto && return x->id.proto == tmpl->id.proto &&
(x->id.spi == tmpl->id.spi || !tmpl->id.spi) && (x->id.spi == tmpl->id.spi || !tmpl->id.spi) &&
(x->props.reqid == tmpl->reqid || !tmpl->reqid) && (x->props.reqid == tmpl->reqid || !tmpl->reqid) &&
...@@ -862,14 +864,23 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x, ...@@ -862,14 +864,23 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x,
} }
static inline int static inline int
xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int idx, xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int start,
unsigned short family) unsigned short family)
{ {
int idx = start;
if (tmpl->optional) {
if (!tmpl->mode)
return start;
} else
start = -1;
for (; idx < sp->len; idx++) { for (; idx < sp->len; idx++) {
if (xfrm_state_ok(tmpl, sp->x[idx].xvec, family)) if (xfrm_state_ok(tmpl, sp->x[idx].xvec, family))
return ++idx; return ++idx;
if (sp->x[idx].xvec->props.mode)
break;
} }
return -1; return start;
} }
static int static int
...@@ -922,32 +933,35 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, ...@@ -922,32 +933,35 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
xfrm_policy_lookup); xfrm_policy_lookup);
if (!pol) if (!pol)
return 1; return !skb->sp;
pol->curlft.use_time = (unsigned long)xtime.tv_sec; pol->curlft.use_time = (unsigned long)xtime.tv_sec;
if (pol->action == XFRM_POLICY_ALLOW) { if (pol->action == XFRM_POLICY_ALLOW) {
if (pol->xfrm_nr != 0) { struct sec_path *sp;
struct sec_path *sp; static struct sec_path dummy;
static struct sec_path dummy; int i, k;
int i, k;
if ((sp = skb->sp) == NULL)
if ((sp = skb->sp) == NULL) sp = &dummy;
sp = &dummy;
/* For each tunnel xfrm, find the first matching tmpl.
/* For each tmpl search corresponding xfrm. * For each tmpl before that, find corresponding xfrm.
* Order is _important_. Later we will implement * Order is _important_. Later we will implement
* some barriers, but at the moment barriers * some barriers, but at the moment barriers
* are implied between each two transformations. * are implied between each two transformations.
*/ */
for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) { for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) {
if (pol->xfrm_vec[i].optional) k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family);
continue; if (k < 0)
k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family); goto reject;
if (k < 0) }
goto reject;
} for (; k < sp->len; k++) {
if (sp->x[k].xvec->props.mode)
goto reject;
} }
xfrm_pol_put(pol); xfrm_pol_put(pol);
return 1; return 1;
} }
......
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