aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorJames Bottomley <jejb@sparkweed.localdomain>2006-09-23 22:03:52 -0400
committerJames Bottomley <jejb@sparkweed.localdomain>2006-09-23 22:03:52 -0400
commit1aedf2ccc60fade26c46fae12e28664d0da3f199 (patch)
treed91083e3079f1ddb942a382ac2b5a7525570ad59 /net/bridge
parentdfdc58ba354adb80d67c99f7be84f95a8e02e466 (diff)
parent1ab9dd0902df4f4ff56fbf672220549090ab28ba (diff)
Merge mulgrave-w:git/linux-2.6
Conflicts: include/linux/blkdev.h Trivial merge to incorporate tag prototypes.
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_forward.c5
-rw-r--r--net/bridge/br_netfilter.c50
-rw-r--r--net/bridge/br_netlink.c31
-rw-r--r--net/bridge/netfilter/ebtables.c97
4 files changed, 93 insertions, 90 deletions
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 864fbbc7b24d..191b861e5e53 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -38,13 +38,10 @@ int br_dev_queue_push_xmit(struct sk_buff *skb)
38 if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb)) 38 if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
39 kfree_skb(skb); 39 kfree_skb(skb);
40 else { 40 else {
41#ifdef CONFIG_BRIDGE_NETFILTER
42 /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */ 41 /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */
43 if (nf_bridge_maybe_copy_header(skb)) 42 if (nf_bridge_maybe_copy_header(skb))
44 kfree_skb(skb); 43 kfree_skb(skb);
45 else 44 else {
46#endif
47 {
48 skb_push(skb, ETH_HLEN); 45 skb_push(skb, ETH_HLEN);
49 46
50 dev_queue_xmit(skb); 47 dev_queue_xmit(skb);
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 05b3de888243..ac181be13d83 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -53,10 +53,10 @@
53 53
54#ifdef CONFIG_SYSCTL 54#ifdef CONFIG_SYSCTL
55static struct ctl_table_header *brnf_sysctl_header; 55static struct ctl_table_header *brnf_sysctl_header;
56static int brnf_call_iptables = 1; 56static int brnf_call_iptables __read_mostly = 1;
57static int brnf_call_ip6tables = 1; 57static int brnf_call_ip6tables __read_mostly = 1;
58static int brnf_call_arptables = 1; 58static int brnf_call_arptables __read_mostly = 1;
59static int brnf_filter_vlan_tagged = 1; 59static int brnf_filter_vlan_tagged __read_mostly = 1;
60#else 60#else
61#define brnf_filter_vlan_tagged 1 61#define brnf_filter_vlan_tagged 1
62#endif 62#endif
@@ -127,14 +127,37 @@ static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
127 127
128static inline void nf_bridge_save_header(struct sk_buff *skb) 128static inline void nf_bridge_save_header(struct sk_buff *skb)
129{ 129{
130 int header_size = 16; 130 int header_size = ETH_HLEN;
131 131
132 if (skb->protocol == htons(ETH_P_8021Q)) 132 if (skb->protocol == htons(ETH_P_8021Q))
133 header_size = 18; 133 header_size += VLAN_HLEN;
134 134
135 memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); 135 memcpy(skb->nf_bridge->data, skb->data - header_size, header_size);
136} 136}
137 137
138/*
139 * When forwarding bridge frames, we save a copy of the original
140 * header before processing.
141 */
142int nf_bridge_copy_header(struct sk_buff *skb)
143{
144 int err;
145 int header_size = ETH_HLEN;
146
147 if (skb->protocol == htons(ETH_P_8021Q))
148 header_size += VLAN_HLEN;
149
150 err = skb_cow(skb, header_size);
151 if (err)
152 return err;
153
154 memcpy(skb->data - header_size, skb->nf_bridge->data, header_size);
155
156 if (skb->protocol == htons(ETH_P_8021Q))
157 __skb_push(skb, VLAN_HLEN);
158 return 0;
159}
160
138/* PF_BRIDGE/PRE_ROUTING *********************************************/ 161/* PF_BRIDGE/PRE_ROUTING *********************************************/
139/* Undo the changes made for ip6tables PREROUTING and continue the 162/* Undo the changes made for ip6tables PREROUTING and continue the
140 * bridge PRE_ROUTING hook. */ 163 * bridge PRE_ROUTING hook. */
@@ -695,16 +718,6 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
695 else 718 else
696 pf = PF_INET6; 719 pf = PF_INET6;
697 720
698#ifdef CONFIG_NETFILTER_DEBUG
699 /* Sometimes we get packets with NULL ->dst here (for example,
700 * running a dhcp client daemon triggers this). This should now
701 * be fixed, but let's keep the check around. */
702 if (skb->dst == NULL) {
703 printk(KERN_CRIT "br_netfilter: skb->dst == NULL.");
704 return NF_ACCEPT;
705 }
706#endif
707
708 nf_bridge = skb->nf_bridge; 721 nf_bridge = skb->nf_bridge;
709 nf_bridge->physoutdev = skb->dev; 722 nf_bridge->physoutdev = skb->dev;
710 realindev = nf_bridge->physindev; 723 realindev = nf_bridge->physindev;
@@ -786,7 +799,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
786 * keep the check just to be sure... */ 799 * keep the check just to be sure... */
787 if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) { 800 if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) {
788 printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: " 801 printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: "
789 "bad mac.raw pointer."); 802 "bad mac.raw pointer.\n");
790 goto print_error; 803 goto print_error;
791 } 804 }
792#endif 805#endif
@@ -804,7 +817,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
804 817
805#ifdef CONFIG_NETFILTER_DEBUG 818#ifdef CONFIG_NETFILTER_DEBUG
806 if (skb->dst == NULL) { 819 if (skb->dst == NULL) {
807 printk(KERN_CRIT "br_netfilter: skb->dst == NULL."); 820 printk(KERN_INFO "br_netfilter post_routing: skb->dst == NULL\n");
808 goto print_error; 821 goto print_error;
809 } 822 }
810#endif 823#endif
@@ -841,6 +854,7 @@ print_error:
841 } 854 }
842 printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw, 855 printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw,
843 skb->data); 856 skb->data);
857 dump_stack();
844 return NF_ACCEPT; 858 return NF_ACCEPT;
845#endif 859#endif
846} 860}
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 53086fb75089..8f661195d09d 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/rtnetlink.h> 14#include <linux/rtnetlink.h>
15#include <net/netlink.h>
15#include "br_private.h" 16#include "br_private.h"
16 17
17/* 18/*
@@ -76,26 +77,24 @@ rtattr_failure:
76void br_ifinfo_notify(int event, struct net_bridge_port *port) 77void br_ifinfo_notify(int event, struct net_bridge_port *port)
77{ 78{
78 struct sk_buff *skb; 79 struct sk_buff *skb;
79 int err = -ENOMEM; 80 int payload = sizeof(struct ifinfomsg) + 128;
81 int err = -ENOBUFS;
80 82
81 pr_debug("bridge notify event=%d\n", event); 83 pr_debug("bridge notify event=%d\n", event);
82 skb = alloc_skb(NLMSG_SPACE(sizeof(struct ifinfomsg) + 128), 84 skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC);
83 GFP_ATOMIC); 85 if (skb == NULL)
84 if (!skb) 86 goto errout;
85 goto err_out; 87
88 err = br_fill_ifinfo(skb, port, 0, 0, event, 0);
89 if (err < 0) {
90 kfree_skb(skb);
91 goto errout;
92 }
86 93
87 err = br_fill_ifinfo(skb, port, current->pid, 0, event, 0); 94 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
95errout:
88 if (err < 0) 96 if (err < 0)
89 goto err_kfree; 97 rtnl_set_sk_err(RTNLGRP_LINK, err);
90
91 NETLINK_CB(skb).dst_group = RTNLGRP_LINK;
92 netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_ATOMIC);
93 return;
94
95err_kfree:
96 kfree_skb(skb);
97err_out:
98 netlink_set_err(rtnl, 0, RTNLGRP_LINK, err);
99} 98}
100 99
101/* 100/*
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 3a13ed643459..3df55b2bd91d 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -24,6 +24,7 @@
24#include <linux/vmalloc.h> 24#include <linux/vmalloc.h>
25#include <linux/netfilter_bridge/ebtables.h> 25#include <linux/netfilter_bridge/ebtables.h>
26#include <linux/spinlock.h> 26#include <linux/spinlock.h>
27#include <linux/mutex.h>
27#include <asm/uaccess.h> 28#include <asm/uaccess.h>
28#include <linux/smp.h> 29#include <linux/smp.h>
29#include <linux/cpumask.h> 30#include <linux/cpumask.h>
@@ -31,36 +32,9 @@
31/* needed for logical [in,out]-dev filtering */ 32/* needed for logical [in,out]-dev filtering */
32#include "../br_private.h" 33#include "../br_private.h"
33 34
34/* list_named_find */
35#define ASSERT_READ_LOCK(x)
36#define ASSERT_WRITE_LOCK(x)
37#include <linux/netfilter_ipv4/listhelp.h>
38#include <linux/mutex.h>
39
40#if 0
41/* use this for remote debugging
42 * Copyright (C) 1998 by Ori Pomerantz
43 * Print the string to the appropriate tty, the one
44 * the current task uses
45 */
46static void print_string(char *str)
47{
48 struct tty_struct *my_tty;
49
50 /* The tty for the current task */
51 my_tty = current->signal->tty;
52 if (my_tty != NULL) {
53 my_tty->driver->write(my_tty, 0, str, strlen(str));
54 my_tty->driver->write(my_tty, 0, "\015\012", 2);
55 }
56}
57
58#define BUGPRINT(args) print_string(args);
59#else
60#define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\ 35#define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\
61 "report to author: "format, ## args) 36 "report to author: "format, ## args)
62/* #define BUGPRINT(format, args...) */ 37/* #define BUGPRINT(format, args...) */
63#endif
64#define MEMPRINT(format, args...) printk("kernel msg: ebtables "\ 38#define MEMPRINT(format, args...) printk("kernel msg: ebtables "\
65 ": out of memory: "format, ## args) 39 ": out of memory: "format, ## args)
66/* #define MEMPRINT(format, args...) */ 40/* #define MEMPRINT(format, args...) */
@@ -299,18 +273,22 @@ static inline void *
299find_inlist_lock_noload(struct list_head *head, const char *name, int *error, 273find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
300 struct mutex *mutex) 274 struct mutex *mutex)
301{ 275{
302 void *ret; 276 struct {
277 struct list_head list;
278 char name[EBT_FUNCTION_MAXNAMELEN];
279 } *e;
303 280
304 *error = mutex_lock_interruptible(mutex); 281 *error = mutex_lock_interruptible(mutex);
305 if (*error != 0) 282 if (*error != 0)
306 return NULL; 283 return NULL;
307 284
308 ret = list_named_find(head, name); 285 list_for_each_entry(e, head, list) {
309 if (!ret) { 286 if (strcmp(e->name, name) == 0)
310 *error = -ENOENT; 287 return e;
311 mutex_unlock(mutex);
312 } 288 }
313 return ret; 289 *error = -ENOENT;
290 mutex_unlock(mutex);
291 return NULL;
314} 292}
315 293
316#ifndef CONFIG_KMOD 294#ifndef CONFIG_KMOD
@@ -1064,15 +1042,19 @@ free_newinfo:
1064 1042
1065int ebt_register_target(struct ebt_target *target) 1043int ebt_register_target(struct ebt_target *target)
1066{ 1044{
1045 struct ebt_target *t;
1067 int ret; 1046 int ret;
1068 1047
1069 ret = mutex_lock_interruptible(&ebt_mutex); 1048 ret = mutex_lock_interruptible(&ebt_mutex);
1070 if (ret != 0) 1049 if (ret != 0)
1071 return ret; 1050 return ret;
1072 if (!list_named_insert(&ebt_targets, target)) { 1051 list_for_each_entry(t, &ebt_targets, list) {
1073 mutex_unlock(&ebt_mutex); 1052 if (strcmp(t->name, target->name) == 0) {
1074 return -EEXIST; 1053 mutex_unlock(&ebt_mutex);
1054 return -EEXIST;
1055 }
1075 } 1056 }
1057 list_add(&target->list, &ebt_targets);
1076 mutex_unlock(&ebt_mutex); 1058 mutex_unlock(&ebt_mutex);
1077 1059
1078 return 0; 1060 return 0;
@@ -1081,21 +1063,25 @@ int ebt_register_target(struct ebt_target *target)
1081void ebt_unregister_target(struct ebt_target *target) 1063void ebt_unregister_target(struct ebt_target *target)
1082{ 1064{
1083 mutex_lock(&ebt_mutex); 1065 mutex_lock(&ebt_mutex);
1084 LIST_DELETE(&ebt_targets, target); 1066 list_del(&target->list);
1085 mutex_unlock(&ebt_mutex); 1067 mutex_unlock(&ebt_mutex);
1086} 1068}
1087 1069
1088int ebt_register_match(struct ebt_match *match) 1070int ebt_register_match(struct ebt_match *match)
1089{ 1071{
1072 struct ebt_match *m;
1090 int ret; 1073 int ret;
1091 1074
1092 ret = mutex_lock_interruptible(&ebt_mutex); 1075 ret = mutex_lock_interruptible(&ebt_mutex);
1093 if (ret != 0) 1076 if (ret != 0)
1094 return ret; 1077 return ret;
1095 if (!list_named_insert(&ebt_matches, match)) { 1078 list_for_each_entry(m, &ebt_matches, list) {
1096 mutex_unlock(&ebt_mutex); 1079 if (strcmp(m->name, match->name) == 0) {
1097 return -EEXIST; 1080 mutex_unlock(&ebt_mutex);
1081 return -EEXIST;
1082 }
1098 } 1083 }
1084 list_add(&match->list, &ebt_matches);
1099 mutex_unlock(&ebt_mutex); 1085 mutex_unlock(&ebt_mutex);
1100 1086
1101 return 0; 1087 return 0;
@@ -1104,21 +1090,25 @@ int ebt_register_match(struct ebt_match *match)
1104void ebt_unregister_match(struct ebt_match *match) 1090void ebt_unregister_match(struct ebt_match *match)
1105{ 1091{
1106 mutex_lock(&ebt_mutex); 1092 mutex_lock(&ebt_mutex);
1107 LIST_DELETE(&ebt_matches, match); 1093 list_del(&match->list);
1108 mutex_unlock(&ebt_mutex); 1094 mutex_unlock(&ebt_mutex);
1109} 1095}
1110 1096
1111int ebt_register_watcher(struct ebt_watcher *watcher) 1097int ebt_register_watcher(struct ebt_watcher *watcher)
1112{ 1098{
1099 struct ebt_watcher *w;
1113 int ret; 1100 int ret;
1114 1101
1115 ret = mutex_lock_interruptible(&ebt_mutex); 1102 ret = mutex_lock_interruptible(&ebt_mutex);
1116 if (ret != 0) 1103 if (ret != 0)
1117 return ret; 1104 return ret;
1118 if (!list_named_insert(&ebt_watchers, watcher)) { 1105 list_for_each_entry(w, &ebt_watchers, list) {
1119 mutex_unlock(&ebt_mutex); 1106 if (strcmp(w->name, watcher->name) == 0) {
1120 return -EEXIST; 1107 mutex_unlock(&ebt_mutex);
1108 return -EEXIST;
1109 }
1121 } 1110 }
1111 list_add(&watcher->list, &ebt_watchers);
1122 mutex_unlock(&ebt_mutex); 1112 mutex_unlock(&ebt_mutex);
1123 1113
1124 return 0; 1114 return 0;
@@ -1127,13 +1117,14 @@ int ebt_register_watcher(struct ebt_watcher *watcher)
1127void ebt_unregister_watcher(struct ebt_watcher *watcher) 1117void ebt_unregister_watcher(struct ebt_watcher *watcher)
1128{ 1118{
1129 mutex_lock(&ebt_mutex); 1119 mutex_lock(&ebt_mutex);
1130 LIST_DELETE(&ebt_watchers, watcher); 1120 list_del(&watcher->list);
1131 mutex_unlock(&ebt_mutex); 1121 mutex_unlock(&ebt_mutex);
1132} 1122}
1133 1123
1134int ebt_register_table(struct ebt_table *table) 1124int ebt_register_table(struct ebt_table *table)
1135{ 1125{
1136 struct ebt_table_info *newinfo; 1126 struct ebt_table_info *newinfo;
1127 struct ebt_table *t;
1137 int ret, i, countersize; 1128 int ret, i, countersize;
1138 1129
1139 if (!table || !table->table ||!table->table->entries || 1130 if (!table || !table->table ||!table->table->entries ||
@@ -1179,10 +1170,12 @@ int ebt_register_table(struct ebt_table *table)
1179 if (ret != 0) 1170 if (ret != 0)
1180 goto free_chainstack; 1171 goto free_chainstack;
1181 1172
1182 if (list_named_find(&ebt_tables, table->name)) { 1173 list_for_each_entry(t, &ebt_tables, list) {
1183 ret = -EEXIST; 1174 if (strcmp(t->name, table->name) == 0) {
1184 BUGPRINT("Table name already exists\n"); 1175 ret = -EEXIST;
1185 goto free_unlock; 1176 BUGPRINT("Table name already exists\n");
1177 goto free_unlock;
1178 }
1186 } 1179 }
1187 1180
1188 /* Hold a reference count if the chains aren't empty */ 1181 /* Hold a reference count if the chains aren't empty */
@@ -1190,7 +1183,7 @@ int ebt_register_table(struct ebt_table *table)
1190 ret = -ENOENT; 1183 ret = -ENOENT;
1191 goto free_unlock; 1184 goto free_unlock;
1192 } 1185 }
1193 list_prepend(&ebt_tables, table); 1186 list_add(&table->list, &ebt_tables);
1194 mutex_unlock(&ebt_mutex); 1187 mutex_unlock(&ebt_mutex);
1195 return 0; 1188 return 0;
1196free_unlock: 1189free_unlock:
@@ -1216,7 +1209,7 @@ void ebt_unregister_table(struct ebt_table *table)
1216 return; 1209 return;
1217 } 1210 }
1218 mutex_lock(&ebt_mutex); 1211 mutex_lock(&ebt_mutex);
1219 LIST_DELETE(&ebt_tables, table); 1212 list_del(&table->list);
1220 mutex_unlock(&ebt_mutex); 1213 mutex_unlock(&ebt_mutex);
1221 vfree(table->private->entries); 1214 vfree(table->private->entries);
1222 if (table->private->chainstack) { 1215 if (table->private->chainstack) {
@@ -1486,7 +1479,7 @@ static int __init ebtables_init(void)
1486 int ret; 1479 int ret;
1487 1480
1488 mutex_lock(&ebt_mutex); 1481 mutex_lock(&ebt_mutex);
1489 list_named_insert(&ebt_targets, &ebt_standard_target); 1482 list_add(&ebt_standard_target.list, &ebt_targets);
1490 mutex_unlock(&ebt_mutex); 1483 mutex_unlock(&ebt_mutex);
1491 if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) 1484 if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
1492 return ret; 1485 return ret;