summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/Kconfig2
-rw-r--r--net/caif/cfrfml.c2
-rw-r--r--net/core/dev.c1
-rw-r--r--net/core/drop_monitor.c23
-rw-r--r--net/core/net-sysfs.c2
-rw-r--r--net/core/pktgen.c36
-rw-r--r--net/core/skbuff.c9
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c2
-rw-r--r--net/ipv4/route.c7
-rw-r--r--net/ipv6/addrconf.c14
-rw-r--r--net/mac80211/cfg.c2
-rw-r--r--net/netlink/af_netlink.c22
-rw-r--r--net/netlink/genetlink.c15
-rw-r--r--net/sched/act_mirred.c43
14 files changed, 109 insertions, 71 deletions
diff --git a/net/Kconfig b/net/Kconfig
index b3250944cde9..e24fa0873f32 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -32,7 +32,7 @@ config WANT_COMPAT_NETLINK_MESSAGES
config COMPAT_NETLINK_MESSAGES
def_bool y
depends on COMPAT
- depends on WIRELESS_EXT || WANT_COMPAT_NETLINK_MESSAGES
+ depends on WEXT_CORE || WANT_COMPAT_NETLINK_MESSAGES
help
This option makes it possible to send different netlink messages
to tasks depending on whether the task is a compat task or not. To
diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c
index 4b04d25b6a3f..eb1602022ac0 100644
--- a/net/caif/cfrfml.c
+++ b/net/caif/cfrfml.c
@@ -193,7 +193,7 @@ out:
static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt)
{
- caif_assert(!cfpkt_getlen(pkt) < rfml->fragment_size);
+ caif_assert(cfpkt_getlen(pkt) >= rfml->fragment_size);
/* Add info for MUX-layer to route the packet out. */
cfpkt_info(pkt)->channel_id = rfml->serv.layer.id;
diff --git a/net/core/dev.c b/net/core/dev.c
index 6e1b4370781c..b74fcd3e9365 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1484,6 +1484,7 @@ static inline void net_timestamp_check(struct sk_buff *skb)
int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
{
skb_orphan(skb);
+ nf_reset(skb);
if (!(dev->flags & IFF_UP) ||
(skb->len > (dev->mtu + dev->hard_header_len))) {
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 646ef3bc7200..36e603c78ce9 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -347,9 +347,9 @@ static struct notifier_block dropmon_net_notifier = {
static int __init init_net_drop_monitor(void)
{
- int cpu;
- int rc, i, ret;
struct per_cpu_dm_data *data;
+ int cpu, rc;
+
printk(KERN_INFO "Initalizing network drop monitor service\n");
if (sizeof(void *) > 8) {
@@ -357,21 +357,12 @@ static int __init init_net_drop_monitor(void)
return -ENOSPC;
}
- if (genl_register_family(&net_drop_monitor_family) < 0) {
+ rc = genl_register_family_with_ops(&net_drop_monitor_family,
+ dropmon_ops,
+ ARRAY_SIZE(dropmon_ops));
+ if (rc) {
printk(KERN_ERR "Could not create drop monitor netlink family\n");
- return -EFAULT;
- }
-
- rc = -EFAULT;
-
- for (i = 0; i < ARRAY_SIZE(dropmon_ops); i++) {
- ret = genl_register_ops(&net_drop_monitor_family,
- &dropmon_ops[i]);
- if (ret) {
- printk(KERN_CRIT "Failed to register operation %d\n",
- dropmon_ops[i].cmd);
- goto out_unreg;
- }
+ return rc;
}
rc = register_netdevice_notifier(&dropmon_net_notifier);
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index d2b596537d41..af4dfbadf2a0 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -95,6 +95,7 @@ static ssize_t netdev_store(struct device *dev, struct device_attribute *attr,
}
NETDEVICE_SHOW(dev_id, fmt_hex);
+NETDEVICE_SHOW(addr_assign_type, fmt_dec);
NETDEVICE_SHOW(addr_len, fmt_dec);
NETDEVICE_SHOW(iflink, fmt_dec);
NETDEVICE_SHOW(ifindex, fmt_dec);
@@ -295,6 +296,7 @@ static ssize_t show_ifalias(struct device *dev,
}
static struct device_attribute net_class_attributes[] = {
+ __ATTR(addr_assign_type, S_IRUGO, show_addr_assign_type, NULL),
__ATTR(addr_len, S_IRUGO, show_addr_len, NULL),
__ATTR(dev_id, S_IRUGO, show_dev_id, NULL),
__ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias),
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 24a19debda1b..10a1ea72010d 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -1434,18 +1434,12 @@ static ssize_t pktgen_if_write(struct file *file,
i += len;
for (*m = 0; *v && m < pkt_dev->dst_mac + 6; v++) {
- if (*v >= '0' && *v <= '9') {
- *m *= 16;
- *m += *v - '0';
- }
- if (*v >= 'A' && *v <= 'F') {
- *m *= 16;
- *m += *v - 'A' + 10;
- }
- if (*v >= 'a' && *v <= 'f') {
- *m *= 16;
- *m += *v - 'a' + 10;
- }
+ int value;
+
+ value = hex_to_bin(*v);
+ if (value >= 0)
+ *m = *m * 16 + value;
+
if (*v == ':') {
m++;
*m = 0;
@@ -1476,18 +1470,12 @@ static ssize_t pktgen_if_write(struct file *file,
i += len;
for (*m = 0; *v && m < pkt_dev->src_mac + 6; v++) {
- if (*v >= '0' && *v <= '9') {
- *m *= 16;
- *m += *v - '0';
- }
- if (*v >= 'A' && *v <= 'F') {
- *m *= 16;
- *m += *v - 'A' + 10;
- }
- if (*v >= 'a' && *v <= 'f') {
- *m *= 16;
- *m += *v - 'a' + 10;
- }
+ int value;
+
+ value = hex_to_bin(*v);
+ if (value >= 0)
+ *m = *m * 16 + value;
+
if (*v == ':') {
m++;
*m = 0;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 76d33ca5f037..3a2513f0d0c3 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -817,7 +817,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
memcpy(data + nhead, skb->head, skb->tail - skb->head);
#endif
memcpy(data + size, skb_end_pointer(skb),
- sizeof(struct skb_shared_info));
+ offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags]));
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
get_page(skb_shinfo(skb)->frags[i].page);
@@ -843,7 +843,9 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
skb->network_header += off;
if (skb_mac_header_was_set(skb))
skb->mac_header += off;
- skb->csum_start += nhead;
+ /* Only adjust this if it actually is csum_start rather than csum */
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ skb->csum_start += nhead;
skb->cloned = 0;
skb->hdr_len = 0;
skb->nohdr = 0;
@@ -930,7 +932,8 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
copy_skb_header(n, skb);
off = newheadroom - oldheadroom;
- n->csum_start += off;
+ if (n->ip_summed == CHECKSUM_PARTIAL)
+ n->csum_start += off;
#ifdef NET_SKBUFF_DATA_USES_OFFSET
n->transport_header += off;
n->network_header += off;
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 64d0875f5192..3a43cf36db87 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -469,7 +469,7 @@ struct arp_payload {
__be32 src_ip;
u_int8_t dst_hw[ETH_ALEN];
__be32 dst_ip;
-} __attribute__ ((packed));
+} __packed;
#ifdef DEBUG
static void arp_print(struct arp_payload *payload)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 562ce92de2a6..3f56b6e6c6aa 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2878,6 +2878,9 @@ static int rt_fill_info(struct net *net,
if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0)
goto nla_put_failure;
+ if (rt->fl.mark)
+ NLA_PUT_BE32(skb, RTA_MARK, rt->fl.mark);
+
error = rt->dst.error;
expires = rt->dst.expires ? rt->dst.expires - jiffies : 0;
if (rt->peer) {
@@ -2933,6 +2936,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
__be32 src = 0;
u32 iif;
int err;
+ int mark;
struct sk_buff *skb;
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv4_policy);
@@ -2960,6 +2964,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
src = tb[RTA_SRC] ? nla_get_be32(tb[RTA_SRC]) : 0;
dst = tb[RTA_DST] ? nla_get_be32(tb[RTA_DST]) : 0;
iif = tb[RTA_IIF] ? nla_get_u32(tb[RTA_IIF]) : 0;
+ mark = tb[RTA_MARK] ? nla_get_u32(tb[RTA_MARK]) : 0;
if (iif) {
struct net_device *dev;
@@ -2972,6 +2977,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
skb->protocol = htons(ETH_P_IP);
skb->dev = dev;
+ skb->mark = mark;
local_bh_disable();
err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev);
local_bh_enable();
@@ -2989,6 +2995,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
},
},
.oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0,
+ .mark = mark,
};
err = ip_route_output_key(net, &rt, &fl);
}
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e81155d2f251..ab70a3fbcafa 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1763,7 +1763,10 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
idev = ipv6_find_idev(dev);
if (!idev)
- return NULL;
+ return ERR_PTR(-ENOBUFS);
+
+ if (idev->cnf.disable_ipv6)
+ return ERR_PTR(-EACCES);
/* Add default multicast route */
addrconf_add_mroute(dev);
@@ -2132,8 +2135,9 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx,
if (!dev)
return -ENODEV;
- if ((idev = addrconf_add_dev(dev)) == NULL)
- return -ENOBUFS;
+ idev = addrconf_add_dev(dev);
+ if (IS_ERR(idev))
+ return PTR_ERR(idev);
scope = ipv6_addr_scope(pfx);
@@ -2380,7 +2384,7 @@ static void addrconf_dev_config(struct net_device *dev)
}
idev = addrconf_add_dev(dev);
- if (idev == NULL)
+ if (IS_ERR(idev))
return;
memset(&addr, 0, sizeof(struct in6_addr));
@@ -2471,7 +2475,7 @@ static void addrconf_ip6_tnl_config(struct net_device *dev)
ASSERT_RTNL();
idev = addrconf_add_dev(dev);
- if (!idev) {
+ if (IS_ERR(idev)) {
printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n");
return;
}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index dab6b8efe5fa..29ac8e1a509e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -627,7 +627,7 @@ static void ieee80211_send_layer2_update(struct sta_info *sta)
skb->dev = sta->sdata->dev;
skb->protocol = eth_type_trans(skb, sta->sdata->dev);
memset(skb->cb, 0, sizeof(skb->cb));
- netif_rx(skb);
+ netif_rx_ni(skb);
}
static void sta_apply_parameters(struct ieee80211_local *local,
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 8648a9922aab..2cbf380377d5 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1406,7 +1406,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
struct netlink_sock *nlk = nlk_sk(sk);
int noblock = flags&MSG_DONTWAIT;
size_t copied;
- struct sk_buff *skb, *frag __maybe_unused = NULL;
+ struct sk_buff *skb;
int err;
if (flags&MSG_OOB)
@@ -1441,7 +1441,21 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
kfree_skb(skb);
skb = compskb;
} else {
- frag = skb_shinfo(skb)->frag_list;
+ /*
+ * Before setting frag_list to NULL, we must get a
+ * private copy of skb if shared (because of MSG_PEEK)
+ */
+ if (skb_shared(skb)) {
+ struct sk_buff *nskb;
+
+ nskb = pskb_copy(skb, GFP_KERNEL);
+ kfree_skb(skb);
+ skb = nskb;
+ err = -ENOMEM;
+ if (!skb)
+ goto out;
+ }
+ kfree_skb(skb_shinfo(skb)->frag_list);
skb_shinfo(skb)->frag_list = NULL;
}
}
@@ -1478,10 +1492,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
if (flags & MSG_TRUNC)
copied = skb->len;
-#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
- skb_shinfo(skb)->frag_list = frag;
-#endif
-
skb_free_datagram(sk, skb);
if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2)
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index aa4308afcc7f..26ed3e8587c2 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -303,6 +303,7 @@ int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
errout:
return err;
}
+EXPORT_SYMBOL(genl_register_ops);
/**
* genl_unregister_ops - unregister generic netlink operations
@@ -337,6 +338,7 @@ int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops)
return -ENOENT;
}
+EXPORT_SYMBOL(genl_unregister_ops);
/**
* genl_register_family - register a generic netlink family
@@ -405,6 +407,7 @@ errout_locked:
errout:
return err;
}
+EXPORT_SYMBOL(genl_register_family);
/**
* genl_register_family_with_ops - register a generic netlink family
@@ -485,6 +488,7 @@ int genl_unregister_family(struct genl_family *family)
return -ENOENT;
}
+EXPORT_SYMBOL(genl_unregister_family);
static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
@@ -873,11 +877,7 @@ static int __init genl_init(void)
for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
INIT_LIST_HEAD(&family_ht[i]);
- err = genl_register_family(&genl_ctrl);
- if (err < 0)
- goto problem;
-
- err = genl_register_ops(&genl_ctrl, &genl_ctrl_ops);
+ err = genl_register_family_with_ops(&genl_ctrl, &genl_ctrl_ops, 1);
if (err < 0)
goto problem;
@@ -899,11 +899,6 @@ problem:
subsys_initcall(genl_init);
-EXPORT_SYMBOL(genl_register_ops);
-EXPORT_SYMBOL(genl_unregister_ops);
-EXPORT_SYMBOL(genl_register_family);
-EXPORT_SYMBOL(genl_unregister_family);
-
static int genlmsg_mcast(struct sk_buff *skb, u32 pid, unsigned long group,
gfp_t flags)
{
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index a16b0175f890..11f195af2da0 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -33,6 +33,7 @@
static struct tcf_common *tcf_mirred_ht[MIRRED_TAB_MASK + 1];
static u32 mirred_idx_gen;
static DEFINE_RWLOCK(mirred_lock);
+static LIST_HEAD(mirred_list);
static struct tcf_hashinfo mirred_hash_info = {
.htab = tcf_mirred_ht,
@@ -47,7 +48,9 @@ static inline int tcf_mirred_release(struct tcf_mirred *m, int bind)
m->tcf_bindcnt--;
m->tcf_refcnt--;
if(!m->tcf_bindcnt && m->tcf_refcnt <= 0) {
- dev_put(m->tcfm_dev);
+ list_del(&m->tcfm_list);
+ if (m->tcfm_dev)
+ dev_put(m->tcfm_dev);
tcf_hash_destroy(&m->common, &mirred_hash_info);
return 1;
}
@@ -134,8 +137,10 @@ static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est,
m->tcfm_ok_push = ok_push;
}
spin_unlock_bh(&m->tcf_lock);
- if (ret == ACT_P_CREATED)
+ if (ret == ACT_P_CREATED) {
+ list_add(&m->tcfm_list, &mirred_list);
tcf_hash_insert(pc, &mirred_hash_info);
+ }
return ret;
}
@@ -164,9 +169,14 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a,
m->tcf_bstats.packets++;
dev = m->tcfm_dev;
+ if (!dev) {
+ printk_once(KERN_NOTICE "tc mirred: target device is gone\n");
+ goto out;
+ }
+
if (!(dev->flags & IFF_UP)) {
if (net_ratelimit())
- pr_notice("tc mirred to Houston: device %s is gone!\n",
+ pr_notice("tc mirred to Houston: device %s is down\n",
dev->name);
goto out;
}
@@ -230,6 +240,28 @@ nla_put_failure:
return -1;
}
+static int mirred_device_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = ptr;
+ struct tcf_mirred *m;
+
+ if (event == NETDEV_UNREGISTER)
+ list_for_each_entry(m, &mirred_list, tcfm_list) {
+ if (m->tcfm_dev == dev) {
+ dev_put(dev);
+ m->tcfm_dev = NULL;
+ }
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block mirred_device_notifier = {
+ .notifier_call = mirred_device_event,
+};
+
+
static struct tc_action_ops act_mirred_ops = {
.kind = "mirred",
.hinfo = &mirred_hash_info,
@@ -250,12 +282,17 @@ MODULE_LICENSE("GPL");
static int __init mirred_init_module(void)
{
+ int err = register_netdevice_notifier(&mirred_device_notifier);
+ if (err)
+ return err;
+
pr_info("Mirror/redirect action on\n");
return tcf_register_action(&act_mirred_ops);
}
static void __exit mirred_cleanup_module(void)
{
+ unregister_netdevice_notifier(&mirred_device_notifier);
tcf_unregister_action(&act_mirred_ops);
}