mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 16:29:05 +00:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
This commit is contained in:
commit
4b0955a6ed
@ -160,7 +160,8 @@ extern int netlink_unregister_notifier(struct notifier_block *nb);
|
|||||||
|
|
||||||
/* finegrained unicast helpers: */
|
/* finegrained unicast helpers: */
|
||||||
struct sock *netlink_getsockbyfilp(struct file *filp);
|
struct sock *netlink_getsockbyfilp(struct file *filp);
|
||||||
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long timeo);
|
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
|
||||||
|
long timeo, struct sock *ssk);
|
||||||
void netlink_detachskb(struct sock *sk, struct sk_buff *skb);
|
void netlink_detachskb(struct sock *sk, struct sk_buff *skb);
|
||||||
int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol);
|
int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol);
|
||||||
|
|
||||||
|
@ -50,6 +50,9 @@
|
|||||||
/* May be different when we get VFIR */
|
/* May be different when we get VFIR */
|
||||||
#define LAP_MAX_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER)
|
#define LAP_MAX_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER)
|
||||||
|
|
||||||
|
/* Each IrDA device gets a random 32 bits IRLAP device address */
|
||||||
|
#define LAP_ALEN 4
|
||||||
|
|
||||||
#define BROADCAST 0xffffffff /* Broadcast device address */
|
#define BROADCAST 0xffffffff /* Broadcast device address */
|
||||||
#define CBROADCAST 0xfe /* Connection broadcast address */
|
#define CBROADCAST 0xfe /* Connection broadcast address */
|
||||||
#define XID_FORMAT 0x01 /* Discovery XID format */
|
#define XID_FORMAT 0x01 /* Discovery XID format */
|
||||||
|
@ -1018,7 +1018,8 @@ retry:
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = netlink_attachskb(sock, nc, 0, MAX_SCHEDULE_TIMEOUT);
|
ret = netlink_attachskb(sock, nc, 0,
|
||||||
|
MAX_SCHEDULE_TIMEOUT, NULL);
|
||||||
if (ret == 1)
|
if (ret == 1)
|
||||||
goto retry;
|
goto retry;
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -79,9 +79,14 @@ static int port_cost(struct net_device *dev)
|
|||||||
*/
|
*/
|
||||||
static void port_carrier_check(void *arg)
|
static void port_carrier_check(void *arg)
|
||||||
{
|
{
|
||||||
struct net_bridge_port *p = arg;
|
struct net_device *dev = arg;
|
||||||
|
struct net_bridge_port *p;
|
||||||
|
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
|
p = dev->br_port;
|
||||||
|
if (!p)
|
||||||
|
goto done;
|
||||||
|
|
||||||
if (netif_carrier_ok(p->dev)) {
|
if (netif_carrier_ok(p->dev)) {
|
||||||
u32 cost = port_cost(p->dev);
|
u32 cost = port_cost(p->dev);
|
||||||
|
|
||||||
@ -97,19 +102,33 @@ static void port_carrier_check(void *arg)
|
|||||||
br_stp_disable_port(p);
|
br_stp_disable_port(p);
|
||||||
spin_unlock_bh(&p->br->lock);
|
spin_unlock_bh(&p->br->lock);
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void release_nbp(struct kobject *kobj)
|
||||||
|
{
|
||||||
|
struct net_bridge_port *p
|
||||||
|
= container_of(kobj, struct net_bridge_port, kobj);
|
||||||
|
kfree(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct kobj_type brport_ktype = {
|
||||||
|
#ifdef CONFIG_SYSFS
|
||||||
|
.sysfs_ops = &brport_sysfs_ops,
|
||||||
|
#endif
|
||||||
|
.release = release_nbp,
|
||||||
|
};
|
||||||
|
|
||||||
static void destroy_nbp(struct net_bridge_port *p)
|
static void destroy_nbp(struct net_bridge_port *p)
|
||||||
{
|
{
|
||||||
struct net_device *dev = p->dev;
|
struct net_device *dev = p->dev;
|
||||||
|
|
||||||
dev->br_port = NULL;
|
|
||||||
p->br = NULL;
|
p->br = NULL;
|
||||||
p->dev = NULL;
|
p->dev = NULL;
|
||||||
dev_put(dev);
|
dev_put(dev);
|
||||||
|
|
||||||
br_sysfs_freeif(p);
|
kobject_put(&p->kobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_nbp_rcu(struct rcu_head *head)
|
static void destroy_nbp_rcu(struct rcu_head *head)
|
||||||
@ -133,24 +152,24 @@ static void del_nbp(struct net_bridge_port *p)
|
|||||||
struct net_bridge *br = p->br;
|
struct net_bridge *br = p->br;
|
||||||
struct net_device *dev = p->dev;
|
struct net_device *dev = p->dev;
|
||||||
|
|
||||||
/* Race between RTNL notify and RCU callback */
|
sysfs_remove_link(&br->ifobj, dev->name);
|
||||||
if (p->deleted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dev_set_promiscuity(dev, -1);
|
dev_set_promiscuity(dev, -1);
|
||||||
|
|
||||||
cancel_delayed_work(&p->carrier_check);
|
cancel_delayed_work(&p->carrier_check);
|
||||||
flush_scheduled_work();
|
|
||||||
|
|
||||||
spin_lock_bh(&br->lock);
|
spin_lock_bh(&br->lock);
|
||||||
br_stp_disable_port(p);
|
br_stp_disable_port(p);
|
||||||
p->deleted = 1;
|
|
||||||
spin_unlock_bh(&br->lock);
|
spin_unlock_bh(&br->lock);
|
||||||
|
|
||||||
br_fdb_delete_by_port(br, p);
|
br_fdb_delete_by_port(br, p);
|
||||||
|
|
||||||
list_del_rcu(&p->list);
|
list_del_rcu(&p->list);
|
||||||
|
|
||||||
|
rcu_assign_pointer(dev->br_port, NULL);
|
||||||
|
|
||||||
|
kobject_del(&p->kobj);
|
||||||
|
|
||||||
call_rcu(&p->rcu, destroy_nbp_rcu);
|
call_rcu(&p->rcu, destroy_nbp_rcu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +179,6 @@ static void del_br(struct net_bridge *br)
|
|||||||
struct net_bridge_port *p, *n;
|
struct net_bridge_port *p, *n;
|
||||||
|
|
||||||
list_for_each_entry_safe(p, n, &br->port_list, list) {
|
list_for_each_entry_safe(p, n, &br->port_list, list) {
|
||||||
br_sysfs_removeif(p);
|
|
||||||
del_nbp(p);
|
del_nbp(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,13 +272,17 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
|
|||||||
p->dev = dev;
|
p->dev = dev;
|
||||||
p->path_cost = port_cost(dev);
|
p->path_cost = port_cost(dev);
|
||||||
p->priority = 0x8000 >> BR_PORT_BITS;
|
p->priority = 0x8000 >> BR_PORT_BITS;
|
||||||
dev->br_port = p;
|
|
||||||
p->port_no = index;
|
p->port_no = index;
|
||||||
br_init_port(p);
|
br_init_port(p);
|
||||||
p->state = BR_STATE_DISABLED;
|
p->state = BR_STATE_DISABLED;
|
||||||
INIT_WORK(&p->carrier_check, port_carrier_check, p);
|
INIT_WORK(&p->carrier_check, port_carrier_check, dev);
|
||||||
kobject_init(&p->kobj);
|
kobject_init(&p->kobj);
|
||||||
|
|
||||||
|
kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR);
|
||||||
|
p->kobj.ktype = &brport_ktype;
|
||||||
|
p->kobj.parent = &(dev->class_dev.kobj);
|
||||||
|
p->kobj.kset = NULL;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,30 +410,43 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
|
|||||||
if (dev->br_port != NULL)
|
if (dev->br_port != NULL)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
if (IS_ERR(p = new_nbp(br, dev)))
|
p = new_nbp(br, dev);
|
||||||
|
if (IS_ERR(p))
|
||||||
return PTR_ERR(p);
|
return PTR_ERR(p);
|
||||||
|
|
||||||
if ((err = br_fdb_insert(br, p, dev->dev_addr)))
|
err = kobject_add(&p->kobj);
|
||||||
destroy_nbp(p);
|
if (err)
|
||||||
|
goto err0;
|
||||||
else if ((err = br_sysfs_addif(p)))
|
|
||||||
del_nbp(p);
|
|
||||||
else {
|
|
||||||
dev_set_promiscuity(dev, 1);
|
|
||||||
|
|
||||||
list_add_rcu(&p->list, &br->port_list);
|
err = br_fdb_insert(br, p, dev->dev_addr);
|
||||||
|
if (err)
|
||||||
|
goto err1;
|
||||||
|
|
||||||
spin_lock_bh(&br->lock);
|
err = br_sysfs_addif(p);
|
||||||
br_stp_recalculate_bridge_id(br);
|
if (err)
|
||||||
br_features_recompute(br);
|
goto err2;
|
||||||
if ((br->dev->flags & IFF_UP)
|
|
||||||
&& (dev->flags & IFF_UP) && netif_carrier_ok(dev))
|
|
||||||
br_stp_enable_port(p);
|
|
||||||
spin_unlock_bh(&br->lock);
|
|
||||||
|
|
||||||
dev_set_mtu(br->dev, br_min_mtu(br));
|
rcu_assign_pointer(dev->br_port, p);
|
||||||
}
|
dev_set_promiscuity(dev, 1);
|
||||||
|
|
||||||
|
list_add_rcu(&p->list, &br->port_list);
|
||||||
|
|
||||||
|
spin_lock_bh(&br->lock);
|
||||||
|
br_stp_recalculate_bridge_id(br);
|
||||||
|
br_features_recompute(br);
|
||||||
|
schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE);
|
||||||
|
spin_unlock_bh(&br->lock);
|
||||||
|
|
||||||
|
dev_set_mtu(br->dev, br_min_mtu(br));
|
||||||
|
kobject_uevent(&p->kobj, KOBJ_ADD);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err2:
|
||||||
|
br_fdb_delete_by_port(br, p);
|
||||||
|
err1:
|
||||||
|
kobject_del(&p->kobj);
|
||||||
|
err0:
|
||||||
|
kobject_put(&p->kobj);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,7 +458,6 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
|
|||||||
if (!p || p->br != br)
|
if (!p || p->br != br)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
br_sysfs_removeif(p);
|
|
||||||
del_nbp(p);
|
del_nbp(p);
|
||||||
|
|
||||||
spin_lock_bh(&br->lock);
|
spin_lock_bh(&br->lock);
|
||||||
|
@ -45,18 +45,20 @@ static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb)
|
|||||||
int br_handle_frame_finish(struct sk_buff *skb)
|
int br_handle_frame_finish(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
const unsigned char *dest = eth_hdr(skb)->h_dest;
|
const unsigned char *dest = eth_hdr(skb)->h_dest;
|
||||||
struct net_bridge_port *p = skb->dev->br_port;
|
struct net_bridge_port *p = rcu_dereference(skb->dev->br_port);
|
||||||
struct net_bridge *br = p->br;
|
struct net_bridge *br;
|
||||||
struct net_bridge_fdb_entry *dst;
|
struct net_bridge_fdb_entry *dst;
|
||||||
int passedup = 0;
|
int passedup = 0;
|
||||||
|
|
||||||
/* insert into forwarding database after filtering to avoid spoofing */
|
if (!p || p->state == BR_STATE_DISABLED)
|
||||||
br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
|
goto drop;
|
||||||
|
|
||||||
if (p->state == BR_STATE_LEARNING) {
|
/* insert into forwarding database after filtering to avoid spoofing */
|
||||||
kfree_skb(skb);
|
br = p->br;
|
||||||
goto out;
|
br_fdb_update(br, p, eth_hdr(skb)->h_source);
|
||||||
}
|
|
||||||
|
if (p->state == BR_STATE_LEARNING)
|
||||||
|
goto drop;
|
||||||
|
|
||||||
if (br->dev->flags & IFF_PROMISC) {
|
if (br->dev->flags & IFF_PROMISC) {
|
||||||
struct sk_buff *skb2;
|
struct sk_buff *skb2;
|
||||||
@ -93,6 +95,9 @@ int br_handle_frame_finish(struct sk_buff *skb)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
return 0;
|
return 0;
|
||||||
|
drop:
|
||||||
|
kfree_skb(skb);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -51,9 +51,6 @@
|
|||||||
#define store_orig_dstaddr(skb) (skb_origaddr(skb) = (skb)->nh.iph->daddr)
|
#define store_orig_dstaddr(skb) (skb_origaddr(skb) = (skb)->nh.iph->daddr)
|
||||||
#define dnat_took_place(skb) (skb_origaddr(skb) != (skb)->nh.iph->daddr)
|
#define dnat_took_place(skb) (skb_origaddr(skb) != (skb)->nh.iph->daddr)
|
||||||
|
|
||||||
#define has_bridge_parent(device) ((device)->br_port != NULL)
|
|
||||||
#define bridge_parent(device) ((device)->br_port->br->dev)
|
|
||||||
|
|
||||||
#ifdef CONFIG_SYSCTL
|
#ifdef CONFIG_SYSCTL
|
||||||
static struct ctl_table_header *brnf_sysctl_header;
|
static struct ctl_table_header *brnf_sysctl_header;
|
||||||
static int brnf_call_iptables = 1;
|
static int brnf_call_iptables = 1;
|
||||||
@ -98,6 +95,12 @@ static struct rtable __fake_rtable = {
|
|||||||
.rt_flags = 0,
|
.rt_flags = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline struct net_device *bridge_parent(const struct net_device *dev)
|
||||||
|
{
|
||||||
|
struct net_bridge_port *port = rcu_dereference(dev->br_port);
|
||||||
|
|
||||||
|
return port ? port->br->dev : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* PF_BRIDGE/PRE_ROUTING *********************************************/
|
/* PF_BRIDGE/PRE_ROUTING *********************************************/
|
||||||
/* Undo the changes made for ip6tables PREROUTING and continue the
|
/* Undo the changes made for ip6tables PREROUTING and continue the
|
||||||
@ -189,11 +192,15 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
|
|||||||
skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
|
skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
|
||||||
|
|
||||||
skb->dev = bridge_parent(skb->dev);
|
skb->dev = bridge_parent(skb->dev);
|
||||||
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
|
if (!skb->dev)
|
||||||
skb_pull(skb, VLAN_HLEN);
|
kfree_skb(skb);
|
||||||
skb->nh.raw += VLAN_HLEN;
|
else {
|
||||||
|
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
|
||||||
|
skb_pull(skb, VLAN_HLEN);
|
||||||
|
skb->nh.raw += VLAN_HLEN;
|
||||||
|
}
|
||||||
|
skb->dst->output(skb);
|
||||||
}
|
}
|
||||||
skb->dst->output(skb);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +277,7 @@ bridged_dnat:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Some common code for IPv4/IPv6 */
|
/* Some common code for IPv4/IPv6 */
|
||||||
static void setup_pre_routing(struct sk_buff *skb)
|
static struct net_device *setup_pre_routing(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
|
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
|
||||||
|
|
||||||
@ -282,6 +289,8 @@ static void setup_pre_routing(struct sk_buff *skb)
|
|||||||
nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
|
nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
|
||||||
nf_bridge->physindev = skb->dev;
|
nf_bridge->physindev = skb->dev;
|
||||||
skb->dev = bridge_parent(skb->dev);
|
skb->dev = bridge_parent(skb->dev);
|
||||||
|
|
||||||
|
return skb->dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We only check the length. A bridge shouldn't do any hop-by-hop stuff anyway */
|
/* We only check the length. A bridge shouldn't do any hop-by-hop stuff anyway */
|
||||||
@ -376,7 +385,8 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
|
|||||||
nf_bridge_put(skb->nf_bridge);
|
nf_bridge_put(skb->nf_bridge);
|
||||||
if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
|
if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
setup_pre_routing(skb);
|
if (!setup_pre_routing(skb))
|
||||||
|
return NF_DROP;
|
||||||
|
|
||||||
NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
|
NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
|
||||||
br_nf_pre_routing_finish_ipv6);
|
br_nf_pre_routing_finish_ipv6);
|
||||||
@ -465,7 +475,8 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
|
|||||||
nf_bridge_put(skb->nf_bridge);
|
nf_bridge_put(skb->nf_bridge);
|
||||||
if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
|
if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
setup_pre_routing(skb);
|
if (!setup_pre_routing(skb))
|
||||||
|
return NF_DROP;
|
||||||
store_orig_dstaddr(skb);
|
store_orig_dstaddr(skb);
|
||||||
|
|
||||||
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
|
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
|
||||||
@ -539,11 +550,16 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
|
|||||||
struct sk_buff *skb = *pskb;
|
struct sk_buff *skb = *pskb;
|
||||||
struct nf_bridge_info *nf_bridge;
|
struct nf_bridge_info *nf_bridge;
|
||||||
struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
|
struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
|
||||||
|
struct net_device *parent;
|
||||||
int pf;
|
int pf;
|
||||||
|
|
||||||
if (!skb->nf_bridge)
|
if (!skb->nf_bridge)
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
|
parent = bridge_parent(out);
|
||||||
|
if (!parent)
|
||||||
|
return NF_DROP;
|
||||||
|
|
||||||
if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP)
|
if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP)
|
||||||
pf = PF_INET;
|
pf = PF_INET;
|
||||||
else
|
else
|
||||||
@ -564,8 +580,8 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
|
|||||||
nf_bridge->mask |= BRNF_BRIDGED;
|
nf_bridge->mask |= BRNF_BRIDGED;
|
||||||
nf_bridge->physoutdev = skb->dev;
|
nf_bridge->physoutdev = skb->dev;
|
||||||
|
|
||||||
NF_HOOK(pf, NF_IP_FORWARD, skb, bridge_parent(in),
|
NF_HOOK(pf, NF_IP_FORWARD, skb, bridge_parent(in), parent,
|
||||||
bridge_parent(out), br_nf_forward_finish);
|
br_nf_forward_finish);
|
||||||
|
|
||||||
return NF_STOLEN;
|
return NF_STOLEN;
|
||||||
}
|
}
|
||||||
@ -688,6 +704,8 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
realoutdev = bridge_parent(skb->dev);
|
realoutdev = bridge_parent(skb->dev);
|
||||||
|
if (!realoutdev)
|
||||||
|
return NF_DROP;
|
||||||
|
|
||||||
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
|
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
|
||||||
/* iptables should match -o br0.x */
|
/* iptables should match -o br0.x */
|
||||||
@ -701,9 +719,11 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
|
|||||||
/* IP forwarded traffic has a physindev, locally
|
/* IP forwarded traffic has a physindev, locally
|
||||||
* generated traffic hasn't. */
|
* generated traffic hasn't. */
|
||||||
if (realindev != NULL) {
|
if (realindev != NULL) {
|
||||||
if (!(nf_bridge->mask & BRNF_DONT_TAKE_PARENT) &&
|
if (!(nf_bridge->mask & BRNF_DONT_TAKE_PARENT) ) {
|
||||||
has_bridge_parent(realindev))
|
struct net_device *parent = bridge_parent(realindev);
|
||||||
realindev = bridge_parent(realindev);
|
if (parent)
|
||||||
|
realindev = parent;
|
||||||
|
}
|
||||||
|
|
||||||
NF_HOOK_THRESH(pf, NF_IP_FORWARD, skb, realindev,
|
NF_HOOK_THRESH(pf, NF_IP_FORWARD, skb, realindev,
|
||||||
realoutdev, br_nf_local_out_finish,
|
realoutdev, br_nf_local_out_finish,
|
||||||
@ -743,6 +763,9 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
|
|||||||
if (!nf_bridge)
|
if (!nf_bridge)
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
|
if (!realoutdev)
|
||||||
|
return NF_DROP;
|
||||||
|
|
||||||
if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP)
|
if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP)
|
||||||
pf = PF_INET;
|
pf = PF_INET;
|
||||||
else
|
else
|
||||||
|
@ -68,7 +68,6 @@ struct net_bridge_port
|
|||||||
/* STP */
|
/* STP */
|
||||||
u8 priority;
|
u8 priority;
|
||||||
u8 state;
|
u8 state;
|
||||||
u8 deleted;
|
|
||||||
u16 port_no;
|
u16 port_no;
|
||||||
unsigned char topology_change_ack;
|
unsigned char topology_change_ack;
|
||||||
unsigned char config_pending;
|
unsigned char config_pending;
|
||||||
@ -233,9 +232,8 @@ extern void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
|
|||||||
|
|
||||||
#ifdef CONFIG_SYSFS
|
#ifdef CONFIG_SYSFS
|
||||||
/* br_sysfs_if.c */
|
/* br_sysfs_if.c */
|
||||||
|
extern struct sysfs_ops brport_sysfs_ops;
|
||||||
extern int br_sysfs_addif(struct net_bridge_port *p);
|
extern int br_sysfs_addif(struct net_bridge_port *p);
|
||||||
extern void br_sysfs_removeif(struct net_bridge_port *p);
|
|
||||||
extern void br_sysfs_freeif(struct net_bridge_port *p);
|
|
||||||
|
|
||||||
/* br_sysfs_br.c */
|
/* br_sysfs_br.c */
|
||||||
extern int br_sysfs_addbr(struct net_device *dev);
|
extern int br_sysfs_addbr(struct net_device *dev);
|
||||||
@ -244,8 +242,6 @@ extern void br_sysfs_delbr(struct net_device *dev);
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#define br_sysfs_addif(p) (0)
|
#define br_sysfs_addif(p) (0)
|
||||||
#define br_sysfs_removeif(p) do { } while(0)
|
|
||||||
#define br_sysfs_freeif(p) kfree(p)
|
|
||||||
#define br_sysfs_addbr(dev) (0)
|
#define br_sysfs_addbr(dev) (0)
|
||||||
#define br_sysfs_delbr(dev) do { } while(0)
|
#define br_sysfs_delbr(dev) do { } while(0)
|
||||||
#endif /* CONFIG_SYSFS */
|
#endif /* CONFIG_SYSFS */
|
||||||
|
@ -133,29 +133,35 @@ void br_send_tcn_bpdu(struct net_bridge_port *p)
|
|||||||
|
|
||||||
static const unsigned char header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
|
static const unsigned char header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
/* NO locks */
|
/* NO locks, but rcu_read_lock (preempt_disabled) */
|
||||||
int br_stp_handle_bpdu(struct sk_buff *skb)
|
int br_stp_handle_bpdu(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct net_bridge_port *p = skb->dev->br_port;
|
struct net_bridge_port *p = rcu_dereference(skb->dev->br_port);
|
||||||
struct net_bridge *br = p->br;
|
struct net_bridge *br;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
br = p->br;
|
||||||
|
spin_lock(&br->lock);
|
||||||
|
|
||||||
|
if (p->state == BR_STATE_DISABLED || !(br->dev->flags & IFF_UP))
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* insert into forwarding database after filtering to avoid spoofing */
|
/* insert into forwarding database after filtering to avoid spoofing */
|
||||||
br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
|
br_fdb_update(br, p, eth_hdr(skb)->h_source);
|
||||||
|
|
||||||
|
if (!br->stp_enabled)
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* need at least the 802 and STP headers */
|
/* need at least the 802 and STP headers */
|
||||||
if (!pskb_may_pull(skb, sizeof(header)+1) ||
|
if (!pskb_may_pull(skb, sizeof(header)+1) ||
|
||||||
memcmp(skb->data, header, sizeof(header)))
|
memcmp(skb->data, header, sizeof(header)))
|
||||||
goto err;
|
goto out;
|
||||||
|
|
||||||
buf = skb_pull(skb, sizeof(header));
|
buf = skb_pull(skb, sizeof(header));
|
||||||
|
|
||||||
spin_lock_bh(&br->lock);
|
|
||||||
if (p->state == BR_STATE_DISABLED
|
|
||||||
|| !(br->dev->flags & IFF_UP)
|
|
||||||
|| !br->stp_enabled)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (buf[0] == BPDU_TYPE_CONFIG) {
|
if (buf[0] == BPDU_TYPE_CONFIG) {
|
||||||
struct br_config_bpdu bpdu;
|
struct br_config_bpdu bpdu;
|
||||||
|
|
||||||
@ -201,7 +207,7 @@ int br_stp_handle_bpdu(struct sk_buff *skb)
|
|||||||
br_received_tcn_bpdu(p);
|
br_received_tcn_bpdu(p);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
spin_unlock_bh(&br->lock);
|
spin_unlock(&br->lock);
|
||||||
err:
|
err:
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -195,23 +195,11 @@ static ssize_t brport_store(struct kobject * kobj,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called from kobject_put when port ref count goes to zero. */
|
struct sysfs_ops brport_sysfs_ops = {
|
||||||
static void brport_release(struct kobject *kobj)
|
|
||||||
{
|
|
||||||
kfree(container_of(kobj, struct net_bridge_port, kobj));
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct sysfs_ops brport_sysfs_ops = {
|
|
||||||
.show = brport_show,
|
.show = brport_show,
|
||||||
.store = brport_store,
|
.store = brport_store,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct kobj_type brport_ktype = {
|
|
||||||
.sysfs_ops = &brport_sysfs_ops,
|
|
||||||
.release = brport_release,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add sysfs entries to ethernet device added to a bridge.
|
* Add sysfs entries to ethernet device added to a bridge.
|
||||||
* Creates a brport subdirectory with bridge attributes.
|
* Creates a brport subdirectory with bridge attributes.
|
||||||
@ -223,17 +211,6 @@ int br_sysfs_addif(struct net_bridge_port *p)
|
|||||||
struct brport_attribute **a;
|
struct brport_attribute **a;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
ASSERT_RTNL();
|
|
||||||
|
|
||||||
kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR);
|
|
||||||
p->kobj.ktype = &brport_ktype;
|
|
||||||
p->kobj.parent = &(p->dev->class_dev.kobj);
|
|
||||||
p->kobj.kset = NULL;
|
|
||||||
|
|
||||||
err = kobject_add(&p->kobj);
|
|
||||||
if(err)
|
|
||||||
goto out1;
|
|
||||||
|
|
||||||
err = sysfs_create_link(&p->kobj, &br->dev->class_dev.kobj,
|
err = sysfs_create_link(&p->kobj, &br->dev->class_dev.kobj,
|
||||||
SYSFS_BRIDGE_PORT_LINK);
|
SYSFS_BRIDGE_PORT_LINK);
|
||||||
if (err)
|
if (err)
|
||||||
@ -245,28 +222,7 @@ int br_sysfs_addif(struct net_bridge_port *p)
|
|||||||
goto out2;
|
goto out2;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = sysfs_create_link(&br->ifobj, &p->kobj, p->dev->name);
|
err= sysfs_create_link(&br->ifobj, &p->kobj, p->dev->name);
|
||||||
if (err)
|
out2:
|
||||||
goto out2;
|
|
||||||
|
|
||||||
kobject_uevent(&p->kobj, KOBJ_ADD);
|
|
||||||
return 0;
|
|
||||||
out2:
|
|
||||||
kobject_del(&p->kobj);
|
|
||||||
out1:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void br_sysfs_removeif(struct net_bridge_port *p)
|
|
||||||
{
|
|
||||||
pr_debug("br_sysfs_removeif\n");
|
|
||||||
sysfs_remove_link(&p->br->ifobj, p->dev->name);
|
|
||||||
kobject_uevent(&p->kobj, KOBJ_REMOVE);
|
|
||||||
kobject_del(&p->kobj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void br_sysfs_freeif(struct net_bridge_port *p)
|
|
||||||
{
|
|
||||||
pr_debug("br_sysfs_freeif\n");
|
|
||||||
kobject_put(&p->kobj);
|
|
||||||
}
|
|
||||||
|
@ -455,7 +455,7 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
|
|||||||
if (!skb)
|
if (!skb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (rtnetlink_fill_ifinfo(skb, dev, type, current->pid, 0, change, 0) < 0) {
|
if (rtnetlink_fill_ifinfo(skb, dev, type, 0, 0, change, 0) < 0) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1135,7 +1135,7 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa)
|
|||||||
|
|
||||||
if (!skb)
|
if (!skb)
|
||||||
netlink_set_err(rtnl, 0, RTNLGRP_IPV4_IFADDR, ENOBUFS);
|
netlink_set_err(rtnl, 0, RTNLGRP_IPV4_IFADDR, ENOBUFS);
|
||||||
else if (inet_fill_ifaddr(skb, ifa, current->pid, 0, event, 0) < 0) {
|
else if (inet_fill_ifaddr(skb, ifa, 0, 0, event, 0) < 0) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
netlink_set_err(rtnl, 0, RTNLGRP_IPV4_IFADDR, EINVAL);
|
netlink_set_err(rtnl, 0, RTNLGRP_IPV4_IFADDR, EINVAL);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1045,7 +1045,7 @@ fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nl->nlmsg_flags = NLM_F_REQUEST;
|
nl->nlmsg_flags = NLM_F_REQUEST;
|
||||||
nl->nlmsg_pid = current->pid;
|
nl->nlmsg_pid = 0;
|
||||||
nl->nlmsg_seq = 0;
|
nl->nlmsg_seq = 0;
|
||||||
nl->nlmsg_len = NLMSG_LENGTH(sizeof(*rtm));
|
nl->nlmsg_len = NLMSG_LENGTH(sizeof(*rtm));
|
||||||
if (cmd == SIOCDELRT) {
|
if (cmd == SIOCDELRT) {
|
||||||
|
@ -456,7 +456,8 @@ void tcp_rcv_space_adjust(struct sock *sk)
|
|||||||
|
|
||||||
tp->rcvq_space.space = space;
|
tp->rcvq_space.space = space;
|
||||||
|
|
||||||
if (sysctl_tcp_moderate_rcvbuf) {
|
if (sysctl_tcp_moderate_rcvbuf &&
|
||||||
|
!(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
|
||||||
int new_clamp = space;
|
int new_clamp = space;
|
||||||
|
|
||||||
/* Receive space grows, normalize in order to
|
/* Receive space grows, normalize in order to
|
||||||
|
@ -343,12 +343,12 @@ static void irda_task_timer_expired(void *data)
|
|||||||
static void irda_device_setup(struct net_device *dev)
|
static void irda_device_setup(struct net_device *dev)
|
||||||
{
|
{
|
||||||
dev->hard_header_len = 0;
|
dev->hard_header_len = 0;
|
||||||
dev->addr_len = 0;
|
dev->addr_len = LAP_ALEN;
|
||||||
|
|
||||||
dev->type = ARPHRD_IRDA;
|
dev->type = ARPHRD_IRDA;
|
||||||
dev->tx_queue_len = 8; /* Window size + 1 s-frame */
|
dev->tx_queue_len = 8; /* Window size + 1 s-frame */
|
||||||
|
|
||||||
memset(dev->broadcast, 0xff, 4);
|
memset(dev->broadcast, 0xff, LAP_ALEN);
|
||||||
|
|
||||||
dev->mtu = 2048;
|
dev->mtu = 2048;
|
||||||
dev->flags = IFF_NOARP;
|
dev->flags = IFF_NOARP;
|
||||||
|
@ -696,7 +696,7 @@ irnet_daddr_to_dname(irnet_socket * self)
|
|||||||
{
|
{
|
||||||
/* Yes !!! Get it.. */
|
/* Yes !!! Get it.. */
|
||||||
strlcpy(self->rname, discoveries[i].info, sizeof(self->rname));
|
strlcpy(self->rname, discoveries[i].info, sizeof(self->rname));
|
||||||
self->rname[NICKNAME_MAX_LEN + 1] = '\0';
|
self->rname[sizeof(self->rname) - 1] = '\0';
|
||||||
DEBUG(IRDA_SERV_INFO, "Device 0x%08x is in fact ``%s''.\n",
|
DEBUG(IRDA_SERV_INFO, "Device 0x%08x is in fact ``%s''.\n",
|
||||||
self->daddr, self->rname);
|
self->daddr, self->rname);
|
||||||
kfree(discoveries);
|
kfree(discoveries);
|
||||||
|
@ -702,7 +702,8 @@ struct sock *netlink_getsockbyfilp(struct file *filp)
|
|||||||
* 0: continue
|
* 0: continue
|
||||||
* 1: repeat lookup - reference dropped while waiting for socket memory.
|
* 1: repeat lookup - reference dropped while waiting for socket memory.
|
||||||
*/
|
*/
|
||||||
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long timeo)
|
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
|
||||||
|
long timeo, struct sock *ssk)
|
||||||
{
|
{
|
||||||
struct netlink_sock *nlk;
|
struct netlink_sock *nlk;
|
||||||
|
|
||||||
@ -712,7 +713,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long t
|
|||||||
test_bit(0, &nlk->state)) {
|
test_bit(0, &nlk->state)) {
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
if (!timeo) {
|
if (!timeo) {
|
||||||
if (!nlk->pid)
|
if (!ssk || nlk_sk(ssk)->pid == 0)
|
||||||
netlink_overrun(sk);
|
netlink_overrun(sk);
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
@ -797,7 +798,7 @@ retry:
|
|||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return PTR_ERR(sk);
|
return PTR_ERR(sk);
|
||||||
}
|
}
|
||||||
err = netlink_attachskb(sk, skb, nonblock, timeo);
|
err = netlink_attachskb(sk, skb, nonblock, timeo, ssk);
|
||||||
if (err == 1)
|
if (err == 1)
|
||||||
goto retry;
|
goto retry;
|
||||||
if (err)
|
if (err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user