diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /net/bridge/netfilter | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'net/bridge/netfilter')
-rw-r--r-- | net/bridge/netfilter/ebt_ip6.c | 3 | ||||
-rw-r--r-- | net/bridge/netfilter/ebt_log.c | 7 | ||||
-rw-r--r-- | net/bridge/netfilter/ebt_stp.c | 4 | ||||
-rw-r--r-- | net/bridge/netfilter/ebt_ulog.c | 37 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtable_broute.c | 4 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtable_filter.c | 4 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtable_nat.c | 4 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 26 |
8 files changed, 45 insertions, 44 deletions
diff --git a/net/bridge/netfilter/ebt_ip6.c b/net/bridge/netfilter/ebt_ip6.c index 99c85668f55..2ed0056a39a 100644 --- a/net/bridge/netfilter/ebt_ip6.c +++ b/net/bridge/netfilter/ebt_ip6.c | |||
@@ -55,10 +55,9 @@ ebt_ip6_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
55 | return false; | 55 | return false; |
56 | if (info->bitmask & EBT_IP6_PROTO) { | 56 | if (info->bitmask & EBT_IP6_PROTO) { |
57 | uint8_t nexthdr = ih6->nexthdr; | 57 | uint8_t nexthdr = ih6->nexthdr; |
58 | __be16 frag_off; | ||
59 | int offset_ph; | 58 | int offset_ph; |
60 | 59 | ||
61 | offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr, &frag_off); | 60 | offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr); |
62 | if (offset_ph == -1) | 61 | if (offset_ph == -1) |
63 | return false; | 62 | return false; |
64 | if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO)) | 63 | if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO)) |
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index 92de5e5f9db..6e5a8bb9b94 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c | |||
@@ -80,7 +80,7 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum, | |||
80 | unsigned int bitmask; | 80 | unsigned int bitmask; |
81 | 81 | ||
82 | spin_lock_bh(&ebt_log_lock); | 82 | spin_lock_bh(&ebt_log_lock); |
83 | printk(KERN_SOH "%c%s IN=%s OUT=%s MAC source = %pM MAC dest = %pM proto = 0x%04x", | 83 | printk("<%c>%s IN=%s OUT=%s MAC source = %pM MAC dest = %pM proto = 0x%04x", |
84 | '0' + loginfo->u.log.level, prefix, | 84 | '0' + loginfo->u.log.level, prefix, |
85 | in ? in->name : "", out ? out->name : "", | 85 | in ? in->name : "", out ? out->name : "", |
86 | eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, | 86 | eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, |
@@ -107,13 +107,12 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum, | |||
107 | goto out; | 107 | goto out; |
108 | } | 108 | } |
109 | 109 | ||
110 | #if IS_ENABLED(CONFIG_BRIDGE_EBT_IP6) | 110 | #if defined(CONFIG_BRIDGE_EBT_IP6) || defined(CONFIG_BRIDGE_EBT_IP6_MODULE) |
111 | if ((bitmask & EBT_LOG_IP6) && eth_hdr(skb)->h_proto == | 111 | if ((bitmask & EBT_LOG_IP6) && eth_hdr(skb)->h_proto == |
112 | htons(ETH_P_IPV6)) { | 112 | htons(ETH_P_IPV6)) { |
113 | const struct ipv6hdr *ih; | 113 | const struct ipv6hdr *ih; |
114 | struct ipv6hdr _iph; | 114 | struct ipv6hdr _iph; |
115 | uint8_t nexthdr; | 115 | uint8_t nexthdr; |
116 | __be16 frag_off; | ||
117 | int offset_ph; | 116 | int offset_ph; |
118 | 117 | ||
119 | ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph); | 118 | ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph); |
@@ -124,7 +123,7 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum, | |||
124 | printk(" IPv6 SRC=%pI6 IPv6 DST=%pI6, IPv6 priority=0x%01X, Next Header=%d", | 123 | printk(" IPv6 SRC=%pI6 IPv6 DST=%pI6, IPv6 priority=0x%01X, Next Header=%d", |
125 | &ih->saddr, &ih->daddr, ih->priority, ih->nexthdr); | 124 | &ih->saddr, &ih->daddr, ih->priority, ih->nexthdr); |
126 | nexthdr = ih->nexthdr; | 125 | nexthdr = ih->nexthdr; |
127 | offset_ph = ipv6_skip_exthdr(skb, sizeof(_iph), &nexthdr, &frag_off); | 126 | offset_ph = ipv6_skip_exthdr(skb, sizeof(_iph), &nexthdr); |
128 | if (offset_ph == -1) | 127 | if (offset_ph == -1) |
129 | goto out; | 128 | goto out; |
130 | print_ports(skb, nexthdr, offset_ph); | 129 | print_ports(skb, nexthdr, offset_ph); |
diff --git a/net/bridge/netfilter/ebt_stp.c b/net/bridge/netfilter/ebt_stp.c index 071d87214dd..5b33a2e634a 100644 --- a/net/bridge/netfilter/ebt_stp.c +++ b/net/bridge/netfilter/ebt_stp.c | |||
@@ -164,8 +164,8 @@ static int ebt_stp_mt_check(const struct xt_mtchk_param *par) | |||
164 | !(info->bitmask & EBT_STP_MASK)) | 164 | !(info->bitmask & EBT_STP_MASK)) |
165 | return -EINVAL; | 165 | return -EINVAL; |
166 | /* Make sure the match only receives stp frames */ | 166 | /* Make sure the match only receives stp frames */ |
167 | if (!ether_addr_equal(e->destmac, bridge_ula) || | 167 | if (compare_ether_addr(e->destmac, bridge_ula) || |
168 | !ether_addr_equal(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) | 168 | compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) |
169 | return -EINVAL; | 169 | return -EINVAL; |
170 | 170 | ||
171 | return 0; | 171 | return 0; |
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index 3476ec46974..bf2a333ca7c 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c | |||
@@ -102,15 +102,16 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size) | |||
102 | unsigned int n; | 102 | unsigned int n; |
103 | 103 | ||
104 | n = max(size, nlbufsiz); | 104 | n = max(size, nlbufsiz); |
105 | skb = alloc_skb(n, GFP_ATOMIC | __GFP_NOWARN); | 105 | skb = alloc_skb(n, GFP_ATOMIC); |
106 | if (!skb) { | 106 | if (!skb) { |
107 | pr_debug("cannot alloc whole buffer of size %ub!\n", n); | ||
107 | if (n > size) { | 108 | if (n > size) { |
108 | /* try to allocate only as much as we need for | 109 | /* try to allocate only as much as we need for |
109 | * current packet */ | 110 | * current packet */ |
110 | skb = alloc_skb(size, GFP_ATOMIC); | 111 | skb = alloc_skb(size, GFP_ATOMIC); |
111 | if (!skb) | 112 | if (!skb) |
112 | pr_debug("cannot even allocate buffer of size %ub\n", | 113 | pr_debug("cannot even allocate " |
113 | size); | 114 | "buffer of size %ub\n", size); |
114 | } | 115 | } |
115 | } | 116 | } |
116 | 117 | ||
@@ -145,24 +146,19 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb, | |||
145 | 146 | ||
146 | if (!ub->skb) { | 147 | if (!ub->skb) { |
147 | if (!(ub->skb = ulog_alloc_skb(size))) | 148 | if (!(ub->skb = ulog_alloc_skb(size))) |
148 | goto unlock; | 149 | goto alloc_failure; |
149 | } else if (size > skb_tailroom(ub->skb)) { | 150 | } else if (size > skb_tailroom(ub->skb)) { |
150 | ulog_send(group); | 151 | ulog_send(group); |
151 | 152 | ||
152 | if (!(ub->skb = ulog_alloc_skb(size))) | 153 | if (!(ub->skb = ulog_alloc_skb(size))) |
153 | goto unlock; | 154 | goto alloc_failure; |
154 | } | 155 | } |
155 | 156 | ||
156 | nlh = nlmsg_put(ub->skb, 0, ub->qlen, 0, | 157 | nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, 0, |
157 | size - NLMSG_ALIGN(sizeof(*nlh)), 0); | 158 | size - NLMSG_ALIGN(sizeof(*nlh))); |
158 | if (!nlh) { | ||
159 | kfree_skb(ub->skb); | ||
160 | ub->skb = NULL; | ||
161 | goto unlock; | ||
162 | } | ||
163 | ub->qlen++; | 159 | ub->qlen++; |
164 | 160 | ||
165 | pm = nlmsg_data(nlh); | 161 | pm = NLMSG_DATA(nlh); |
166 | 162 | ||
167 | /* Fill in the ulog data */ | 163 | /* Fill in the ulog data */ |
168 | pm->version = EBT_ULOG_VERSION; | 164 | pm->version = EBT_ULOG_VERSION; |
@@ -214,6 +210,14 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb, | |||
214 | 210 | ||
215 | unlock: | 211 | unlock: |
216 | spin_unlock_bh(lock); | 212 | spin_unlock_bh(lock); |
213 | |||
214 | return; | ||
215 | |||
216 | nlmsg_failure: | ||
217 | pr_debug("error during NLMSG_PUT. This should " | ||
218 | "not happen, please report to author.\n"); | ||
219 | alloc_failure: | ||
220 | goto unlock; | ||
217 | } | 221 | } |
218 | 222 | ||
219 | /* this function is registered with the netfilter core */ | 223 | /* this function is registered with the netfilter core */ |
@@ -282,9 +286,6 @@ static int __init ebt_ulog_init(void) | |||
282 | { | 286 | { |
283 | int ret; | 287 | int ret; |
284 | int i; | 288 | int i; |
285 | struct netlink_kernel_cfg cfg = { | ||
286 | .groups = EBT_ULOG_MAXNLGROUPS, | ||
287 | }; | ||
288 | 289 | ||
289 | if (nlbufsiz >= 128*1024) { | 290 | if (nlbufsiz >= 128*1024) { |
290 | pr_warning("Netlink buffer has to be <= 128kB," | 291 | pr_warning("Netlink buffer has to be <= 128kB," |
@@ -298,7 +299,9 @@ static int __init ebt_ulog_init(void) | |||
298 | spin_lock_init(&ulog_buffers[i].lock); | 299 | spin_lock_init(&ulog_buffers[i].lock); |
299 | } | 300 | } |
300 | 301 | ||
301 | ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, &cfg); | 302 | ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, |
303 | EBT_ULOG_MAXNLGROUPS, NULL, NULL, | ||
304 | THIS_MODULE); | ||
302 | if (!ebtulognl) | 305 | if (!ebtulognl) |
303 | ret = -ENOMEM; | 306 | ret = -ENOMEM; |
304 | else if ((ret = xt_register_target(&ebt_ulog_tg_reg)) != 0) | 307 | else if ((ret = xt_register_target(&ebt_ulog_tg_reg)) != 0) |
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c index 40d8258bf74..1bcaf36ad61 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c | |||
@@ -87,14 +87,14 @@ static int __init ebtable_broute_init(void) | |||
87 | if (ret < 0) | 87 | if (ret < 0) |
88 | return ret; | 88 | return ret; |
89 | /* see br_input.c */ | 89 | /* see br_input.c */ |
90 | RCU_INIT_POINTER(br_should_route_hook, | 90 | rcu_assign_pointer(br_should_route_hook, |
91 | (br_should_route_hook_t *)ebt_broute); | 91 | (br_should_route_hook_t *)ebt_broute); |
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | static void __exit ebtable_broute_fini(void) | 95 | static void __exit ebtable_broute_fini(void) |
96 | { | 96 | { |
97 | RCU_INIT_POINTER(br_should_route_hook, NULL); | 97 | rcu_assign_pointer(br_should_route_hook, NULL); |
98 | synchronize_net(); | 98 | synchronize_net(); |
99 | unregister_pernet_subsys(&broute_net_ops); | 99 | unregister_pernet_subsys(&broute_net_ops); |
100 | } | 100 | } |
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c index 3c2e9dced9e..42e6bd09457 100644 --- a/net/bridge/netfilter/ebtable_filter.c +++ b/net/bridge/netfilter/ebtable_filter.c | |||
@@ -100,7 +100,9 @@ static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { | |||
100 | static int __net_init frame_filter_net_init(struct net *net) | 100 | static int __net_init frame_filter_net_init(struct net *net) |
101 | { | 101 | { |
102 | net->xt.frame_filter = ebt_register_table(net, &frame_filter); | 102 | net->xt.frame_filter = ebt_register_table(net, &frame_filter); |
103 | return PTR_RET(net->xt.frame_filter); | 103 | if (IS_ERR(net->xt.frame_filter)) |
104 | return PTR_ERR(net->xt.frame_filter); | ||
105 | return 0; | ||
104 | } | 106 | } |
105 | 107 | ||
106 | static void __net_exit frame_filter_net_exit(struct net *net) | 108 | static void __net_exit frame_filter_net_exit(struct net *net) |
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c index 10871bc7790..6dc2f878ae0 100644 --- a/net/bridge/netfilter/ebtable_nat.c +++ b/net/bridge/netfilter/ebtable_nat.c | |||
@@ -100,7 +100,9 @@ static struct nf_hook_ops ebt_ops_nat[] __read_mostly = { | |||
100 | static int __net_init frame_nat_net_init(struct net *net) | 100 | static int __net_init frame_nat_net_init(struct net *net) |
101 | { | 101 | { |
102 | net->xt.frame_nat = ebt_register_table(net, &frame_nat); | 102 | net->xt.frame_nat = ebt_register_table(net, &frame_nat); |
103 | return PTR_RET(net->xt.frame_nat); | 103 | if (IS_ERR(net->xt.frame_nat)) |
104 | return PTR_ERR(net->xt.frame_nat); | ||
105 | return 0; | ||
104 | } | 106 | } |
105 | 107 | ||
106 | static void __net_exit frame_nat_net_exit(struct net *net) | 108 | static void __net_exit frame_nat_net_exit(struct net *net) |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 5fe2ff3b01e..5864cc49136 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -1335,12 +1335,7 @@ static inline int ebt_make_matchname(const struct ebt_entry_match *m, | |||
1335 | const char *base, char __user *ubase) | 1335 | const char *base, char __user *ubase) |
1336 | { | 1336 | { |
1337 | char __user *hlp = ubase + ((char *)m - base); | 1337 | char __user *hlp = ubase + ((char *)m - base); |
1338 | char name[EBT_FUNCTION_MAXNAMELEN] = {}; | 1338 | if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN)) |
1339 | |||
1340 | /* ebtables expects 32 bytes long names but xt_match names are 29 bytes | ||
1341 | long. Copy 29 bytes and fill remaining bytes with zeroes. */ | ||
1342 | strncpy(name, m->u.match->name, sizeof(name)); | ||
1343 | if (copy_to_user(hlp, name, EBT_FUNCTION_MAXNAMELEN)) | ||
1344 | return -EFAULT; | 1339 | return -EFAULT; |
1345 | return 0; | 1340 | return 0; |
1346 | } | 1341 | } |
@@ -1349,10 +1344,7 @@ static inline int ebt_make_watchername(const struct ebt_entry_watcher *w, | |||
1349 | const char *base, char __user *ubase) | 1344 | const char *base, char __user *ubase) |
1350 | { | 1345 | { |
1351 | char __user *hlp = ubase + ((char *)w - base); | 1346 | char __user *hlp = ubase + ((char *)w - base); |
1352 | char name[EBT_FUNCTION_MAXNAMELEN] = {}; | 1347 | if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN)) |
1353 | |||
1354 | strncpy(name, w->u.watcher->name, sizeof(name)); | ||
1355 | if (copy_to_user(hlp , name, EBT_FUNCTION_MAXNAMELEN)) | ||
1356 | return -EFAULT; | 1348 | return -EFAULT; |
1357 | return 0; | 1349 | return 0; |
1358 | } | 1350 | } |
@@ -1363,7 +1355,6 @@ ebt_make_names(struct ebt_entry *e, const char *base, char __user *ubase) | |||
1363 | int ret; | 1355 | int ret; |
1364 | char __user *hlp; | 1356 | char __user *hlp; |
1365 | const struct ebt_entry_target *t; | 1357 | const struct ebt_entry_target *t; |
1366 | char name[EBT_FUNCTION_MAXNAMELEN] = {}; | ||
1367 | 1358 | ||
1368 | if (e->bitmask == 0) | 1359 | if (e->bitmask == 0) |
1369 | return 0; | 1360 | return 0; |
@@ -1377,8 +1368,7 @@ ebt_make_names(struct ebt_entry *e, const char *base, char __user *ubase) | |||
1377 | ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase); | 1368 | ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase); |
1378 | if (ret != 0) | 1369 | if (ret != 0) |
1379 | return ret; | 1370 | return ret; |
1380 | strncpy(name, t->u.target->name, sizeof(name)); | 1371 | if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN)) |
1381 | if (copy_to_user(hlp, name, EBT_FUNCTION_MAXNAMELEN)) | ||
1382 | return -EFAULT; | 1372 | return -EFAULT; |
1383 | return 0; | 1373 | return 0; |
1384 | } | 1374 | } |
@@ -1903,7 +1893,10 @@ static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt, | |||
1903 | 1893 | ||
1904 | switch (compat_mwt) { | 1894 | switch (compat_mwt) { |
1905 | case EBT_COMPAT_MATCH: | 1895 | case EBT_COMPAT_MATCH: |
1906 | match = xt_request_find_match(NFPROTO_BRIDGE, name, 0); | 1896 | match = try_then_request_module(xt_find_match(NFPROTO_BRIDGE, |
1897 | name, 0), "ebt_%s", name); | ||
1898 | if (match == NULL) | ||
1899 | return -ENOENT; | ||
1907 | if (IS_ERR(match)) | 1900 | if (IS_ERR(match)) |
1908 | return PTR_ERR(match); | 1901 | return PTR_ERR(match); |
1909 | 1902 | ||
@@ -1922,7 +1915,10 @@ static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt, | |||
1922 | break; | 1915 | break; |
1923 | case EBT_COMPAT_WATCHER: /* fallthrough */ | 1916 | case EBT_COMPAT_WATCHER: /* fallthrough */ |
1924 | case EBT_COMPAT_TARGET: | 1917 | case EBT_COMPAT_TARGET: |
1925 | wt = xt_request_find_target(NFPROTO_BRIDGE, name, 0); | 1918 | wt = try_then_request_module(xt_find_target(NFPROTO_BRIDGE, |
1919 | name, 0), "ebt_%s", name); | ||
1920 | if (wt == NULL) | ||
1921 | return -ENOENT; | ||
1926 | if (IS_ERR(wt)) | 1922 | if (IS_ERR(wt)) |
1927 | return PTR_ERR(wt); | 1923 | return PTR_ERR(wt); |
1928 | off = xt_compat_target_offset(wt); | 1924 | off = xt_compat_target_offset(wt); |