summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.ninka.net>2003-10-24 09:04:48 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2003-10-24 09:04:48 -0700
commit63244616c5239fa6d44e1f8b63e6239b28f89288 (patch)
treea07f87ae4bd5cfd2c522c20dd3b0bbf39023a946
parent80d63a948ca886eccaa2371e16f286ca50d55fc6 (diff)
parent20b58805034f95684abe868ccbac1df7fdac0e39 (diff)
Merge nuts.ninka.net:/disk1/davem/BK/network-2.5
into nuts.ninka.net:/disk1/davem/BK/net-2.5
-rw-r--r--Documentation/networking/irda.txt10
-rw-r--r--include/linux/in.h24
-rw-r--r--include/linux/socket.h30
-rw-r--r--net/core/sock.c10
-rw-r--r--net/ipv4/ipmr.c68
-rw-r--r--net/ipv4/tcp_ipv4.c9
-rw-r--r--net/ipv6/xfrm6_policy.c2
-rw-r--r--net/xfrm/xfrm_policy.c60
8 files changed, 116 insertions, 97 deletions
diff --git a/Documentation/networking/irda.txt b/Documentation/networking/irda.txt
index a4b5a110db78..9e5b8e66d6a5 100644
--- a/Documentation/networking/irda.txt
+++ b/Documentation/networking/irda.txt
@@ -3,12 +3,12 @@ of the IrDA Utilities. More detailed information about these and associated
programs can be found on http://irda.sourceforge.net/
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
-<wehe@mobilix.org>
+Linux Infared HOWTO (http://www.tuxmobil.org/Infrared-HOWTO/Infrared-HOWTO.html)
+by Werner Heuser <wehe@tuxmobil.org>
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>
diff --git a/include/linux/in.h b/include/linux/in.h
index 5a5efb354b49..fb88c66d748d 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -140,29 +140,29 @@ struct ip_msfilter {
struct group_req
{
- __u32 gr_interface; /* interface index */
- struct sockaddr_storage gr_group; /* group address */
+ __u32 gr_interface; /* interface index */
+ struct __kernel_sockaddr_storage gr_group; /* group address */
};
struct group_source_req
{
- __u32 gsr_interface; /* interface index */
- struct sockaddr_storage gsr_group; /* group address */
- struct sockaddr_storage gsr_source; /* source address */
+ __u32 gsr_interface; /* interface index */
+ struct __kernel_sockaddr_storage gsr_group; /* group address */
+ struct __kernel_sockaddr_storage gsr_source; /* source address */
};
struct group_filter
{
- __u32 gf_interface; /* interface index */
- struct sockaddr_storage gf_group; /* multicast address */
- __u32 gf_fmode; /* filter mode */
- __u32 gf_numsrc; /* number of sources */
- struct sockaddr_storage gf_slist[1]; /* interface index */
+ __u32 gf_interface; /* interface index */
+ struct __kernel_sockaddr_storage gf_group; /* multicast address */
+ __u32 gf_fmode; /* filter mode */
+ __u32 gf_numsrc; /* number of sources */
+ struct __kernel_sockaddr_storage gf_slist[1]; /* interface index */
};
#define GROUP_FILTER_SIZE(numsrc) \
- (sizeof(struct group_filter) - sizeof(struct sockaddr_storage) \
- + (numsrc) * sizeof(struct sockaddr_storage))
+ (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \
+ + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
struct in_pktinfo
{
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 72b8b6fa3d96..0010dee5f9a2 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -1,6 +1,21 @@
#ifndef _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)
#include <linux/config.h> /* for CONFIG_COMPAT */
@@ -27,20 +42,7 @@ struct linger {
int l_linger; /* How long to linger for */
};
-/*
- * 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 */
+#define sockaddr_storage __kernel_sockaddr_storage
/*
* As we do 4.4BSD message passing we use a 4.4BSD message passing
diff --git a/net/core/sock.c b/net/core/sock.c
index cc811e985cee..9d51516eaa56 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -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)
{
- printk(KERN_WARNING "process `%s' is using obsolete "
- "%s SO_BSDCOMPAT\n", current->comm, name);
+ static int warned;
+ 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++;
+ }
}
/*
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 6d5e29bfee60..2f3f7152dcd5 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1124,18 +1124,16 @@ static inline int ipmr_forward_finish(struct sk_buff *skb)
* Processing handlers for ipmr_forward
*/
-static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
- int vifi, int last)
+static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi);
{
struct iphdr *iph = skb->nh.iph;
struct vif_device *vif = &vif_table[vifi];
struct net_device *dev;
struct rtable *rt;
int encap = 0;
- struct sk_buff *skb2;
if (vif->dev == NULL)
- return;
+ goto out_free;
#ifdef CONFIG_IP_PIMSM
if (vif->flags & VIFF_REGISTER) {
@@ -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_packets++;
ipmr_cache_report(skb, vifi, IGMPMSG_WHOLEPKT);
+ kfree_skb(skb);
return;
}
#endif
@@ -1156,7 +1155,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
.tos = RT_TOS(iph->tos) } },
.proto = IPPROTO_IPIP };
if (ip_route_output_key(&rt, &fl))
- return;
+ goto out_free;
encap = sizeof(struct iphdr);
} else {
struct flowi fl = { .oif = vif->link,
@@ -1165,7 +1164,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
.tos = RT_TOS(iph->tos) } },
.proto = IPPROTO_IPIP };
if (ip_route_output_key(&rt, &fl))
- return;
+ goto out_free;
}
dev = rt->u.dst.dev;
@@ -1178,43 +1177,34 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
IP_INC_STATS_BH(IpFragFails);
ip_rt_put(rt);
- return;
+ goto out_free;
}
- encap += LL_RESERVED_SPACE(dev);
-
- 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;
- }
+ encap += LL_RESERVED_SPACE(dev) + rt->u.dst.header_len;
- if (skb2 == NULL) {
- ip_rt_put(rt);
- return;
+ if (skb_cow(skb, encap)) {
+ ip_rt_put(rt);
+ goto out_free;
}
vif->pkt_out++;
vif->bytes_out+=skb->len;
- dst_release(skb2->dst);
- skb2->dst = &rt->u.dst;
- iph = skb2->nh.iph;
+ dst_release(skb->dst);
+ skb->dst = &rt->u.dst;
+ iph = skb->nh.iph;
ip_decrease_ttl(iph);
/* FIXME: forward and output firewalls used to be called here.
* What do we do with netfilter? -- RR */
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 */
((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
@@ -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
* 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);
+ return;
+
+out_free:
+ kfree_skb(skb);
+ return;
}
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
*/
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 (psend != -1)
- ipmr_queue_xmit(skb, cache, psend, 0);
+ if (psend != -1) {
+ struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
+ if (skb2)
+ ipmr_queue_xmit(skb2, cache, psend);
+ }
psend=ct;
}
}
- if (psend != -1)
- ipmr_queue_xmit(skb, cache, psend, !local);
+ if (psend != -1) {
+ 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:
if (!local)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 357727193da8..f8ed24da50be 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1465,15 +1465,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
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;
tcp_openreq_init(req, &tp, skb);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index ef4fca0306a2..bf4fc78d56d6 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -169,7 +169,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
dst_prev->output = dst_prev->xfrm->type->output;
/* Sheit... I remember I did this right. Apparently,
* 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_node = rt0->rt6i_node;
x->u.rt6.rt6i_gateway = rt0->rt6i_gateway;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index b12fb6b5b337..f2bfc4c2e072 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -853,6 +853,8 @@ static inline int
xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x,
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 &&
(x->id.spi == tmpl->id.spi || !tmpl->id.spi) &&
(x->props.reqid == tmpl->reqid || !tmpl->reqid) &&
@@ -862,14 +864,23 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x,
}
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)
{
+ int idx = start;
+
+ if (tmpl->optional) {
+ if (!tmpl->mode)
+ return start;
+ } else
+ start = -1;
for (; idx < sp->len; idx++) {
if (xfrm_state_ok(tmpl, sp->x[idx].xvec, family))
return ++idx;
+ if (sp->x[idx].xvec->props.mode)
+ break;
}
- return -1;
+ return start;
}
static int
@@ -922,32 +933,35 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
xfrm_policy_lookup);
if (!pol)
- return 1;
+ return !skb->sp;
pol->curlft.use_time = (unsigned long)xtime.tv_sec;
if (pol->action == XFRM_POLICY_ALLOW) {
- if (pol->xfrm_nr != 0) {
- struct sec_path *sp;
- static struct sec_path dummy;
- int i, k;
-
- if ((sp = skb->sp) == NULL)
- sp = &dummy;
-
- /* For each tmpl search corresponding xfrm.
- * Order is _important_. Later we will implement
- * some barriers, but at the moment barriers
- * are implied between each two transformations.
- */
- for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) {
- if (pol->xfrm_vec[i].optional)
- continue;
- k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family);
- if (k < 0)
- goto reject;
- }
+ struct sec_path *sp;
+ static struct sec_path dummy;
+ int i, k;
+
+ if ((sp = skb->sp) == NULL)
+ sp = &dummy;
+
+ /* For each tunnel xfrm, find the first matching tmpl.
+ * For each tmpl before that, find corresponding xfrm.
+ * Order is _important_. Later we will implement
+ * some barriers, but at the moment barriers
+ * are implied between each two transformations.
+ */
+ for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) {
+ k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family);
+ if (k < 0)
+ goto reject;
+ }
+
+ for (; k < sp->len; k++) {
+ if (sp->x[k].xvec->props.mode)
+ goto reject;
}
+
xfrm_pol_put(pol);
return 1;
}