aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 96443055324e..13a0d9f6da54 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -98,6 +98,7 @@
98#include <linux/seq_file.h> 98#include <linux/seq_file.h>
99#include <linux/stat.h> 99#include <linux/stat.h>
100#include <linux/if_bridge.h> 100#include <linux/if_bridge.h>
101#include <linux/if_macvlan.h>
101#include <net/dst.h> 102#include <net/dst.h>
102#include <net/pkt_sched.h> 103#include <net/pkt_sched.h>
103#include <net/checksum.h> 104#include <net/checksum.h>
@@ -1813,6 +1814,28 @@ static inline struct sk_buff *handle_bridge(struct sk_buff *skb,
1813#define handle_bridge(skb, pt_prev, ret, orig_dev) (skb) 1814#define handle_bridge(skb, pt_prev, ret, orig_dev) (skb)
1814#endif 1815#endif
1815 1816
1817#if defined(CONFIG_MACVLAN) || defined(CONFIG_MACVLAN_MODULE)
1818struct sk_buff *(*macvlan_handle_frame_hook)(struct sk_buff *skb) __read_mostly;
1819EXPORT_SYMBOL_GPL(macvlan_handle_frame_hook);
1820
1821static inline struct sk_buff *handle_macvlan(struct sk_buff *skb,
1822 struct packet_type **pt_prev,
1823 int *ret,
1824 struct net_device *orig_dev)
1825{
1826 if (skb->dev->macvlan_port == NULL)
1827 return skb;
1828
1829 if (*pt_prev) {
1830 *ret = deliver_skb(skb, *pt_prev, orig_dev);
1831 *pt_prev = NULL;
1832 }
1833 return macvlan_handle_frame_hook(skb);
1834}
1835#else
1836#define handle_macvlan(skb, pt_prev, ret, orig_dev) (skb)
1837#endif
1838
1816#ifdef CONFIG_NET_CLS_ACT 1839#ifdef CONFIG_NET_CLS_ACT
1817/* TODO: Maybe we should just force sch_ingress to be compiled in 1840/* TODO: Maybe we should just force sch_ingress to be compiled in
1818 * when CONFIG_NET_CLS_ACT is? otherwise some useless instructions 1841 * when CONFIG_NET_CLS_ACT is? otherwise some useless instructions
@@ -1920,6 +1943,9 @@ ncls:
1920 skb = handle_bridge(skb, &pt_prev, &ret, orig_dev); 1943 skb = handle_bridge(skb, &pt_prev, &ret, orig_dev);
1921 if (!skb) 1944 if (!skb)
1922 goto out; 1945 goto out;
1946 skb = handle_macvlan(skb, &pt_prev, &ret, orig_dev);
1947 if (!skb)
1948 goto out;
1923 1949
1924 type = skb->protocol; 1950 type = skb->protocol;
1925 list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) { 1951 list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {
@@ -2521,6 +2547,8 @@ static void __dev_set_promiscuity(struct net_device *dev, int inc)
2521{ 2547{
2522 unsigned short old_flags = dev->flags; 2548 unsigned short old_flags = dev->flags;
2523 2549
2550 ASSERT_RTNL();
2551
2524 if ((dev->promiscuity += inc) == 0) 2552 if ((dev->promiscuity += inc) == 0)
2525 dev->flags &= ~IFF_PROMISC; 2553 dev->flags &= ~IFF_PROMISC;
2526 else 2554 else
@@ -2535,6 +2563,9 @@ static void __dev_set_promiscuity(struct net_device *dev, int inc)
2535 dev->name, (dev->flags & IFF_PROMISC), 2563 dev->name, (dev->flags & IFF_PROMISC),
2536 (old_flags & IFF_PROMISC), 2564 (old_flags & IFF_PROMISC),
2537 audit_get_loginuid(current->audit_context)); 2565 audit_get_loginuid(current->audit_context));
2566
2567 if (dev->change_rx_flags)
2568 dev->change_rx_flags(dev, IFF_PROMISC);
2538 } 2569 }
2539} 2570}
2540 2571
@@ -2573,11 +2604,16 @@ void dev_set_allmulti(struct net_device *dev, int inc)
2573{ 2604{
2574 unsigned short old_flags = dev->flags; 2605 unsigned short old_flags = dev->flags;
2575 2606
2607 ASSERT_RTNL();
2608
2576 dev->flags |= IFF_ALLMULTI; 2609 dev->flags |= IFF_ALLMULTI;
2577 if ((dev->allmulti += inc) == 0) 2610 if ((dev->allmulti += inc) == 0)
2578 dev->flags &= ~IFF_ALLMULTI; 2611 dev->flags &= ~IFF_ALLMULTI;
2579 if (dev->flags ^ old_flags) 2612 if (dev->flags ^ old_flags) {
2613 if (dev->change_rx_flags)
2614 dev->change_rx_flags(dev, IFF_ALLMULTI);
2580 dev_set_rx_mode(dev); 2615 dev_set_rx_mode(dev);
2616 }
2581} 2617}
2582 2618
2583/* 2619/*
@@ -2778,6 +2814,8 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
2778 int ret, changes; 2814 int ret, changes;
2779 int old_flags = dev->flags; 2815 int old_flags = dev->flags;
2780 2816
2817 ASSERT_RTNL();
2818
2781 /* 2819 /*
2782 * Set the flags on our device. 2820 * Set the flags on our device.
2783 */ 2821 */
@@ -2792,6 +2830,9 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
2792 * Load in the correct multicast list now the flags have changed. 2830 * Load in the correct multicast list now the flags have changed.
2793 */ 2831 */
2794 2832
2833 if (dev->change_rx_flags && (dev->flags ^ flags) & IFF_MULTICAST)
2834 dev->change_rx_flags(dev, IFF_MULTICAST);
2835
2795 dev_set_rx_mode(dev); 2836 dev_set_rx_mode(dev);
2796 2837
2797 /* 2838 /*