From 53d38430fa11ef28487e81c068db801bd84ff84e Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Mon, 26 Nov 2012 00:38:50 +0100 Subject: [PATCH] --- yaml --- r: 341653 b: refs/heads/master c: af5d4f7737963f2112f148f97c5820425f050650 h: refs/heads/master i: 341651: 76a226054091fa51981249788016a0fbf1043718 v: v3 --- [refs] | 2 +- trunk/drivers/isdn/mISDN/tei.c | 20 +- trunk/drivers/net/bonding/bond_alb.c | 197 +++--------------- trunk/drivers/net/bonding/bond_alb.h | 28 +-- trunk/drivers/net/bonding/bond_debugfs.c | 5 +- trunk/drivers/net/bonding/bonding.h | 13 -- trunk/drivers/net/can/dev.c | 3 +- trunk/drivers/net/can/mscan/mscan.c | 8 + trunk/drivers/net/can/mscan/mscan.h | 1 + trunk/drivers/net/can/sja1000/sja1000.c | 8 + trunk/drivers/net/can/sja1000/sja1000.h | 1 + trunk/drivers/net/can/usb/ems_usb.c | 7 + trunk/drivers/net/can/usb/esd_usb2.c | 10 + .../net/can/usb/peak_usb/pcan_usb_core.c | 5 + .../net/can/usb/peak_usb/pcan_usb_core.h | 1 + .../include/linux/netfilter_ipv6/ip6_tables.h | 9 + trunk/include/linux/openvswitch.h | 1 - trunk/include/net/ipv6.h | 10 - trunk/net/8021q/vlan.c | 1 - trunk/net/batman-adv/hard-interface.c | 3 +- trunk/net/batman-adv/packet.h | 2 - trunk/net/batman-adv/send.c | 6 +- trunk/net/batman-adv/soft-interface.c | 9 +- trunk/net/ieee802154/6lowpan.c | 3 +- trunk/net/ipv6/exthdrs_core.c | 124 ----------- trunk/net/ipv6/netfilter/ip6_tables.c | 103 +++++++++ trunk/net/mac802154/tx.c | 7 +- trunk/net/mac802154/wpan.c | 4 +- trunk/net/netfilter/ipvs/ip_vs_core.c | 4 +- trunk/net/netfilter/xt_HMARK.c | 8 +- trunk/net/openvswitch/actions.c | 97 --------- trunk/net/openvswitch/datapath.c | 27 +-- trunk/net/openvswitch/flow.c | 28 +-- trunk/net/openvswitch/flow.h | 8 +- trunk/net/openvswitch/vport-netdev.c | 14 +- trunk/net/openvswitch/vport-netdev.h | 3 - trunk/net/openvswitch/vport.c | 5 +- trunk/net/sctp/ipv6.c | 2 +- 38 files changed, 244 insertions(+), 543 deletions(-) diff --git a/[refs] b/[refs] index 3254f644ba87..59fa6cafae32 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ee3f34e857238a4552c68d860348893d7728bcab +refs/heads/master: af5d4f7737963f2112f148f97c5820425f050650 diff --git a/trunk/drivers/isdn/mISDN/tei.c b/trunk/drivers/isdn/mISDN/tei.c index 592f597d8951..be88728f1106 100644 --- a/trunk/drivers/isdn/mISDN/tei.c +++ b/trunk/drivers/isdn/mISDN/tei.c @@ -250,7 +250,7 @@ tei_debug(struct FsmInst *fi, char *fmt, ...) static int get_free_id(struct manager *mgr) { - DECLARE_BITMAP(ids, 64) = { [0 ... BITS_TO_LONGS(64) - 1] = 0 }; + u64 ids = 0; int i; struct layer2 *l2; @@ -261,11 +261,11 @@ get_free_id(struct manager *mgr) __func__); return -EBUSY; } - __set_bit(l2->ch.nr, ids); + test_and_set_bit(l2->ch.nr, (u_long *)&ids); } - i = find_next_zero_bit(ids, 64, 1); - if (i < 64) - return i; + for (i = 1; i < 64; i++) + if (!test_bit(i, (u_long *)&ids)) + return i; printk(KERN_WARNING "%s: more as 63 layer2 for one device\n", __func__); return -EBUSY; @@ -274,7 +274,7 @@ get_free_id(struct manager *mgr) static int get_free_tei(struct manager *mgr) { - DECLARE_BITMAP(ids, 64) = { [0 ... BITS_TO_LONGS(64) - 1] = 0 }; + u64 ids = 0; int i; struct layer2 *l2; @@ -288,11 +288,11 @@ get_free_tei(struct manager *mgr) continue; i -= 64; - __set_bit(i, ids); + test_and_set_bit(i, (u_long *)&ids); } - i = find_first_zero_bit(ids, 64); - if (i < 64) - return i + 64; + for (i = 0; i < 64; i++) + if (!test_bit(i, (u_long *)&ids)) + return i + 64; printk(KERN_WARNING "%s: more as 63 dynamic tei for one device\n", __func__); return -1; diff --git a/trunk/drivers/net/bonding/bond_alb.c b/trunk/drivers/net/bonding/bond_alb.c index 7c9d136e74be..e15cc11edbbe 100644 --- a/trunk/drivers/net/bonding/bond_alb.c +++ b/trunk/drivers/net/bonding/bond_alb.c @@ -84,10 +84,6 @@ static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb) /* Forward declaration */ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]); -static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp); -static void rlb_src_unlink(struct bonding *bond, u32 index); -static void rlb_src_link(struct bonding *bond, u32 ip_src_hash, - u32 ip_dst_hash); static inline u8 _simple_hash(const u8 *hash_start, int hash_size) { @@ -358,18 +354,6 @@ static int rlb_arp_recv(const struct sk_buff *skb, struct bonding *bond, if (!arp) goto out; - /* We received an ARP from arp->ip_src. - * We might have used this IP address previously (on the bonding host - * itself or on a system that is bridged together with the bond). - * However, if arp->mac_src is different than what is stored in - * rx_hashtbl, some other host is now using the IP and we must prevent - * sending out client updates with this IP address and the old MAC - * address. - * Clean up all hash table entries that have this address as ip_src but - * have a different mac_src. - */ - rlb_purge_src_ip(bond, arp); - if (arp->op_code == htons(ARPOP_REPLY)) { /* update rx hash table for this ARP */ rlb_update_entry_from_arp(bond, arp); @@ -448,9 +432,9 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave) _lock_rx_hashtbl_bh(bond); rx_hash_table = bond_info->rx_hashtbl; - index = bond_info->rx_hashtbl_used_head; + index = bond_info->rx_hashtbl_head; for (; index != RLB_NULL_INDEX; index = next_index) { - next_index = rx_hash_table[index].used_next; + next_index = rx_hash_table[index].next; if (rx_hash_table[index].slave == slave) { struct slave *assigned_slave = rlb_next_rx_slave(bond); @@ -535,9 +519,8 @@ static void rlb_update_rx_clients(struct bonding *bond) _lock_rx_hashtbl_bh(bond); - hash_index = bond_info->rx_hashtbl_used_head; - for (; hash_index != RLB_NULL_INDEX; - hash_index = client_info->used_next) { + hash_index = bond_info->rx_hashtbl_head; + for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { client_info = &(bond_info->rx_hashtbl[hash_index]); if (client_info->ntt) { rlb_update_client(client_info); @@ -565,9 +548,8 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla _lock_rx_hashtbl_bh(bond); - hash_index = bond_info->rx_hashtbl_used_head; - for (; hash_index != RLB_NULL_INDEX; - hash_index = client_info->used_next) { + hash_index = bond_info->rx_hashtbl_head; + for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { client_info = &(bond_info->rx_hashtbl[hash_index]); if ((client_info->slave == slave) && @@ -596,9 +578,8 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip) _lock_rx_hashtbl(bond); - hash_index = bond_info->rx_hashtbl_used_head; - for (; hash_index != RLB_NULL_INDEX; - hash_index = client_info->used_next) { + hash_index = bond_info->rx_hashtbl_head; + for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { client_info = &(bond_info->rx_hashtbl[hash_index]); if (!client_info->slave) { @@ -644,7 +625,6 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon /* update mac address from arp */ memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); } - memcpy(client_info->mac_src, arp->mac_src, ETH_ALEN); assigned_slave = client_info->slave; if (assigned_slave) { @@ -667,17 +647,6 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon assigned_slave = rlb_next_rx_slave(bond); if (assigned_slave) { - if (!(client_info->assigned && - client_info->ip_src == arp->ip_src)) { - /* ip_src is going to be updated, - * fix the src hash list - */ - u32 hash_src = _simple_hash((u8 *)&arp->ip_src, - sizeof(arp->ip_src)); - rlb_src_unlink(bond, hash_index); - rlb_src_link(bond, hash_src, hash_index); - } - client_info->ip_src = arp->ip_src; client_info->ip_dst = arp->ip_dst; /* arp->mac_dst is broadcast for arp reqeusts. @@ -685,7 +654,6 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon * upon receiving an arp reply. */ memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN); - memcpy(client_info->mac_src, arp->mac_src, ETH_ALEN); client_info->slave = assigned_slave; if (!ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) { @@ -701,11 +669,11 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon } if (!client_info->assigned) { - u32 prev_tbl_head = bond_info->rx_hashtbl_used_head; - bond_info->rx_hashtbl_used_head = hash_index; - client_info->used_next = prev_tbl_head; + u32 prev_tbl_head = bond_info->rx_hashtbl_head; + bond_info->rx_hashtbl_head = hash_index; + client_info->next = prev_tbl_head; if (prev_tbl_head != RLB_NULL_INDEX) { - bond_info->rx_hashtbl[prev_tbl_head].used_prev = + bond_info->rx_hashtbl[prev_tbl_head].prev = hash_index; } client_info->assigned = 1; @@ -726,12 +694,6 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) struct arp_pkt *arp = arp_pkt(skb); struct slave *tx_slave = NULL; - /* Don't modify or load balance ARPs that do not originate locally - * (e.g.,arrive via a bridge). - */ - if (!bond_slave_has_mac(bond, arp->mac_src)) - return NULL; - if (arp->op_code == htons(ARPOP_REPLY)) { /* the arp must be sent on the selected * rx channel @@ -778,9 +740,8 @@ static void rlb_rebalance(struct bonding *bond) _lock_rx_hashtbl_bh(bond); ntt = 0; - hash_index = bond_info->rx_hashtbl_used_head; - for (; hash_index != RLB_NULL_INDEX; - hash_index = client_info->used_next) { + hash_index = bond_info->rx_hashtbl_head; + for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { client_info = &(bond_info->rx_hashtbl[hash_index]); assigned_slave = rlb_next_rx_slave(bond); if (assigned_slave && (client_info->slave != assigned_slave)) { @@ -798,113 +759,11 @@ static void rlb_rebalance(struct bonding *bond) } /* Caller must hold rx_hashtbl lock */ -static void rlb_init_table_entry_dst(struct rlb_client_info *entry) -{ - entry->used_next = RLB_NULL_INDEX; - entry->used_prev = RLB_NULL_INDEX; - entry->assigned = 0; - entry->slave = NULL; - entry->tag = 0; -} -static void rlb_init_table_entry_src(struct rlb_client_info *entry) -{ - entry->src_first = RLB_NULL_INDEX; - entry->src_prev = RLB_NULL_INDEX; - entry->src_next = RLB_NULL_INDEX; -} - static void rlb_init_table_entry(struct rlb_client_info *entry) { memset(entry, 0, sizeof(struct rlb_client_info)); - rlb_init_table_entry_dst(entry); - rlb_init_table_entry_src(entry); -} - -static void rlb_delete_table_entry_dst(struct bonding *bond, u32 index) -{ - struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); - u32 next_index = bond_info->rx_hashtbl[index].used_next; - u32 prev_index = bond_info->rx_hashtbl[index].used_prev; - - if (index == bond_info->rx_hashtbl_used_head) - bond_info->rx_hashtbl_used_head = next_index; - if (prev_index != RLB_NULL_INDEX) - bond_info->rx_hashtbl[prev_index].used_next = next_index; - if (next_index != RLB_NULL_INDEX) - bond_info->rx_hashtbl[next_index].used_prev = prev_index; -} - -/* unlink a rlb hash table entry from the src list */ -static void rlb_src_unlink(struct bonding *bond, u32 index) -{ - struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); - u32 next_index = bond_info->rx_hashtbl[index].src_next; - u32 prev_index = bond_info->rx_hashtbl[index].src_prev; - - bond_info->rx_hashtbl[index].src_next = RLB_NULL_INDEX; - bond_info->rx_hashtbl[index].src_prev = RLB_NULL_INDEX; - - if (next_index != RLB_NULL_INDEX) - bond_info->rx_hashtbl[next_index].src_prev = prev_index; - - if (prev_index == RLB_NULL_INDEX) - return; - - /* is prev_index pointing to the head of this list? */ - if (bond_info->rx_hashtbl[prev_index].src_first == index) - bond_info->rx_hashtbl[prev_index].src_first = next_index; - else - bond_info->rx_hashtbl[prev_index].src_next = next_index; - -} - -static void rlb_delete_table_entry(struct bonding *bond, u32 index) -{ - struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); - struct rlb_client_info *entry = &(bond_info->rx_hashtbl[index]); - - rlb_delete_table_entry_dst(bond, index); - rlb_init_table_entry_dst(entry); - - rlb_src_unlink(bond, index); -} - -/* add the rx_hashtbl[ip_dst_hash] entry to the list - * of entries with identical ip_src_hash - */ -static void rlb_src_link(struct bonding *bond, u32 ip_src_hash, u32 ip_dst_hash) -{ - struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); - u32 next; - - bond_info->rx_hashtbl[ip_dst_hash].src_prev = ip_src_hash; - next = bond_info->rx_hashtbl[ip_src_hash].src_first; - bond_info->rx_hashtbl[ip_dst_hash].src_next = next; - if (next != RLB_NULL_INDEX) - bond_info->rx_hashtbl[next].src_prev = ip_dst_hash; - bond_info->rx_hashtbl[ip_src_hash].src_first = ip_dst_hash; -} - -/* deletes all rx_hashtbl entries with arp->ip_src if their mac_src does - * not match arp->mac_src */ -static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp) -{ - struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); - u32 ip_src_hash = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src)); - u32 index; - - _lock_rx_hashtbl_bh(bond); - - index = bond_info->rx_hashtbl[ip_src_hash].src_first; - while (index != RLB_NULL_INDEX) { - struct rlb_client_info *entry = &(bond_info->rx_hashtbl[index]); - u32 next_index = entry->src_next; - if (entry->ip_src == arp->ip_src && - !ether_addr_equal_64bits(arp->mac_src, entry->mac_src)) - rlb_delete_table_entry(bond, index); - index = next_index; - } - _unlock_rx_hashtbl_bh(bond); + entry->next = RLB_NULL_INDEX; + entry->prev = RLB_NULL_INDEX; } static int rlb_initialize(struct bonding *bond) @@ -922,7 +781,7 @@ static int rlb_initialize(struct bonding *bond) bond_info->rx_hashtbl = new_hashtbl; - bond_info->rx_hashtbl_used_head = RLB_NULL_INDEX; + bond_info->rx_hashtbl_head = RLB_NULL_INDEX; for (i = 0; i < RLB_HASH_TABLE_SIZE; i++) { rlb_init_table_entry(bond_info->rx_hashtbl + i); @@ -944,7 +803,7 @@ static void rlb_deinitialize(struct bonding *bond) kfree(bond_info->rx_hashtbl); bond_info->rx_hashtbl = NULL; - bond_info->rx_hashtbl_used_head = RLB_NULL_INDEX; + bond_info->rx_hashtbl_head = RLB_NULL_INDEX; _unlock_rx_hashtbl_bh(bond); } @@ -956,13 +815,25 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id) _lock_rx_hashtbl_bh(bond); - curr_index = bond_info->rx_hashtbl_used_head; + curr_index = bond_info->rx_hashtbl_head; while (curr_index != RLB_NULL_INDEX) { struct rlb_client_info *curr = &(bond_info->rx_hashtbl[curr_index]); - u32 next_index = bond_info->rx_hashtbl[curr_index].used_next; + u32 next_index = bond_info->rx_hashtbl[curr_index].next; + u32 prev_index = bond_info->rx_hashtbl[curr_index].prev; + + if (curr->tag && (curr->vlan_id == vlan_id)) { + if (curr_index == bond_info->rx_hashtbl_head) { + bond_info->rx_hashtbl_head = next_index; + } + if (prev_index != RLB_NULL_INDEX) { + bond_info->rx_hashtbl[prev_index].next = next_index; + } + if (next_index != RLB_NULL_INDEX) { + bond_info->rx_hashtbl[next_index].prev = prev_index; + } - if (curr->tag && (curr->vlan_id == vlan_id)) - rlb_delete_table_entry(bond, curr_index); + rlb_init_table_entry(curr); + } curr_index = next_index; } diff --git a/trunk/drivers/net/bonding/bond_alb.h b/trunk/drivers/net/bonding/bond_alb.h index e7a5b8b37ea3..90f140a2d197 100644 --- a/trunk/drivers/net/bonding/bond_alb.h +++ b/trunk/drivers/net/bonding/bond_alb.h @@ -94,35 +94,15 @@ struct tlb_client_info { /* ------------------------------------------------------------------------- * struct rlb_client_info contains all info related to a specific rx client - * connection. This is the Clients Hash Table entry struct. - * Note that this is not a proper hash table; if a new client's IP address - * hash collides with an existing client entry, the old entry is replaced. - * - * There is a linked list (linked by the used_next and used_prev members) - * linking all the used entries of the hash table. This allows updating - * all the clients without walking over all the unused elements of the table. - * - * There are also linked lists of entries with identical hash(ip_src). These - * allow cleaning up the table from ip_src<->mac_src associations that have - * become outdated and would cause sending out invalid ARP updates to the - * network. These are linked by the (src_next and src_prev members). + * connection. This is the Clients Hash Table entry struct * ------------------------------------------------------------------------- */ struct rlb_client_info { __be32 ip_src; /* the server IP address */ __be32 ip_dst; /* the client IP address */ - u8 mac_src[ETH_ALEN]; /* the server MAC address */ u8 mac_dst[ETH_ALEN]; /* the client MAC address */ - - /* list of used hash table entries, starting at rx_hashtbl_used_head */ - u32 used_next; - u32 used_prev; - - /* ip_src based hashing */ - u32 src_next; /* next entry with same hash(ip_src) */ - u32 src_prev; /* prev entry with same hash(ip_src) */ - u32 src_first; /* first entry with hash(ip_src) == this entry's index */ - + u32 next; /* The next Hash table entry index */ + u32 prev; /* The previous Hash table entry index */ u8 assigned; /* checking whether this entry is assigned */ u8 ntt; /* flag - need to transmit client info */ struct slave *slave; /* the slave assigned to this client */ @@ -151,7 +131,7 @@ struct alb_bond_info { int rlb_enabled; struct rlb_client_info *rx_hashtbl; /* Receive hash table */ spinlock_t rx_hashtbl_lock; - u32 rx_hashtbl_used_head; + u32 rx_hashtbl_head; u8 rx_ntt; /* flag - need to transmit * to all rx clients */ diff --git a/trunk/drivers/net/bonding/bond_debugfs.c b/trunk/drivers/net/bonding/bond_debugfs.c index 5fc4c2351478..2cf084eb9d52 100644 --- a/trunk/drivers/net/bonding/bond_debugfs.c +++ b/trunk/drivers/net/bonding/bond_debugfs.c @@ -31,9 +31,8 @@ static int bond_debug_rlb_hash_show(struct seq_file *m, void *v) spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); - hash_index = bond_info->rx_hashtbl_used_head; - for (; hash_index != RLB_NULL_INDEX; - hash_index = client_info->used_next) { + hash_index = bond_info->rx_hashtbl_head; + for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { client_info = &(bond_info->rx_hashtbl[hash_index]); seq_printf(m, "%-15pI4 %-15pI4 %-17pM %s\n", &client_info->ip_src, diff --git a/trunk/drivers/net/bonding/bonding.h b/trunk/drivers/net/bonding/bonding.h index 6dded569b111..f8af2fcd3d16 100644 --- a/trunk/drivers/net/bonding/bonding.h +++ b/trunk/drivers/net/bonding/bonding.h @@ -22,7 +22,6 @@ #include #include #include -#include #include "bond_3ad.h" #include "bond_alb.h" @@ -451,18 +450,6 @@ static inline void bond_destroy_proc_dir(struct bond_net *bn) } #endif -static inline struct slave *bond_slave_has_mac(struct bonding *bond, - const u8 *mac) -{ - int i = 0; - struct slave *tmp; - - bond_for_each_slave(bond, tmp, i) - if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr)) - return tmp; - - return NULL; -} /* exported from bond_main.c */ extern int bond_net_id; diff --git a/trunk/drivers/net/can/dev.c b/trunk/drivers/net/can/dev.c index 8233e5ed2939..963e2ccd10db 100644 --- a/trunk/drivers/net/can/dev.c +++ b/trunk/drivers/net/can/dev.c @@ -609,7 +609,8 @@ void close_candev(struct net_device *dev) { struct can_priv *priv = netdev_priv(dev); - del_timer_sync(&priv->restart_timer); + if (del_timer_sync(&priv->restart_timer)) + dev_put(dev); can_flush_echo_skb(dev); } EXPORT_SYMBOL_GPL(close_candev); diff --git a/trunk/drivers/net/can/mscan/mscan.c b/trunk/drivers/net/can/mscan/mscan.c index e6b40954e204..2b104d5f422c 100644 --- a/trunk/drivers/net/can/mscan/mscan.c +++ b/trunk/drivers/net/can/mscan/mscan.c @@ -517,8 +517,12 @@ static irqreturn_t mscan_isr(int irq, void *dev_id) static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode) { + struct mscan_priv *priv = netdev_priv(dev); int ret = 0; + if (!priv->open_time) + return -EINVAL; + switch (mode) { case CAN_MODE_START: ret = mscan_restart(dev); @@ -586,6 +590,8 @@ static int mscan_open(struct net_device *dev) goto exit_napi_disable; } + priv->open_time = jiffies; + if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) setbits8(®s->canctl1, MSCAN_LISTEN); else @@ -600,6 +606,7 @@ static int mscan_open(struct net_device *dev) return 0; exit_free_irq: + priv->open_time = 0; free_irq(dev->irq, dev); exit_napi_disable: napi_disable(&priv->napi); @@ -620,6 +627,7 @@ static int mscan_close(struct net_device *dev) mscan_set_mode(dev, MSCAN_INIT_MODE); close_candev(dev); free_irq(dev->irq, dev); + priv->open_time = 0; return 0; } diff --git a/trunk/drivers/net/can/mscan/mscan.h b/trunk/drivers/net/can/mscan/mscan.h index af2ed8baf0a3..b43e9f5d3268 100644 --- a/trunk/drivers/net/can/mscan/mscan.h +++ b/trunk/drivers/net/can/mscan/mscan.h @@ -281,6 +281,7 @@ struct tx_queue_entry { struct mscan_priv { struct can_priv can; /* must be the first member */ unsigned int type; /* MSCAN type variants */ + long open_time; unsigned long flags; void __iomem *reg_base; /* ioremap'ed address to registers */ u8 shadow_statflg; diff --git a/trunk/drivers/net/can/sja1000/sja1000.c b/trunk/drivers/net/can/sja1000/sja1000.c index 83ee11eca0e2..25011dbe1b96 100644 --- a/trunk/drivers/net/can/sja1000/sja1000.c +++ b/trunk/drivers/net/can/sja1000/sja1000.c @@ -188,6 +188,11 @@ static void sja1000_start(struct net_device *dev) static int sja1000_set_mode(struct net_device *dev, enum can_mode mode) { + struct sja1000_priv *priv = netdev_priv(dev); + + if (!priv->open_time) + return -EINVAL; + switch (mode) { case CAN_MODE_START: sja1000_start(dev); @@ -574,6 +579,7 @@ static int sja1000_open(struct net_device *dev) /* init and start chi */ sja1000_start(dev); + priv->open_time = jiffies; netif_start_queue(dev); @@ -592,6 +598,8 @@ static int sja1000_close(struct net_device *dev) close_candev(dev); + priv->open_time = 0; + return 0; } diff --git a/trunk/drivers/net/can/sja1000/sja1000.h b/trunk/drivers/net/can/sja1000/sja1000.h index afa99847a510..23fff06875f5 100644 --- a/trunk/drivers/net/can/sja1000/sja1000.h +++ b/trunk/drivers/net/can/sja1000/sja1000.h @@ -152,6 +152,7 @@ */ struct sja1000_priv { struct can_priv can; /* must be the first member */ + int open_time; struct sk_buff *echo_skb; /* the lower-layer is responsible for appropriate locking */ diff --git a/trunk/drivers/net/can/usb/ems_usb.c b/trunk/drivers/net/can/usb/ems_usb.c index c69f0b72b352..086fa321677a 100644 --- a/trunk/drivers/net/can/usb/ems_usb.c +++ b/trunk/drivers/net/can/usb/ems_usb.c @@ -245,6 +245,7 @@ struct ems_tx_urb_context { struct ems_usb { struct can_priv can; /* must be the first member */ + int open_time; struct sk_buff *echo_skb[MAX_TX_URBS]; @@ -727,6 +728,7 @@ static int ems_usb_open(struct net_device *netdev) return err; } + dev->open_time = jiffies; netif_start_queue(netdev); @@ -876,6 +878,8 @@ static int ems_usb_close(struct net_device *netdev) close_candev(netdev); + dev->open_time = 0; + return 0; } @@ -901,6 +905,9 @@ static int ems_usb_set_mode(struct net_device *netdev, enum can_mode mode) { struct ems_usb *dev = netdev_priv(netdev); + if (!dev->open_time) + return -EINVAL; + switch (mode) { case CAN_MODE_START: if (ems_usb_write_mode(dev, SJA1000_MOD_NORMAL)) diff --git a/trunk/drivers/net/can/usb/esd_usb2.c b/trunk/drivers/net/can/usb/esd_usb2.c index 9b74d1e3ad44..124e0dd3490c 100644 --- a/trunk/drivers/net/can/usb/esd_usb2.c +++ b/trunk/drivers/net/can/usb/esd_usb2.c @@ -217,6 +217,7 @@ struct esd_usb2_net_priv { struct usb_anchor tx_submitted; struct esd_tx_urb_context tx_contexts[MAX_TX_URBS]; + int open_time; struct esd_usb2 *usb2; struct net_device *netdev; int index; @@ -694,6 +695,8 @@ static int esd_usb2_open(struct net_device *netdev) return err; } + priv->open_time = jiffies; + netif_start_queue(netdev); return 0; @@ -861,6 +864,8 @@ static int esd_usb2_close(struct net_device *netdev) close_candev(netdev); + priv->open_time = 0; + return 0; } @@ -936,6 +941,11 @@ static int esd_usb2_get_berr_counter(const struct net_device *netdev, static int esd_usb2_set_mode(struct net_device *netdev, enum can_mode mode) { + struct esd_usb2_net_priv *priv = netdev_priv(netdev); + + if (!priv->open_time) + return -EINVAL; + switch (mode) { case CAN_MODE_START: netif_wake_queue(netdev); diff --git a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_core.c index d9290ea788e0..c4643c400d46 100644 --- a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_core.c +++ b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_core.c @@ -520,6 +520,7 @@ static int peak_usb_ndo_open(struct net_device *netdev) return err; } + dev->open_time = jiffies; netif_start_queue(netdev); return 0; @@ -575,6 +576,7 @@ static int peak_usb_ndo_stop(struct net_device *netdev) close_candev(netdev); + dev->open_time = 0; dev->can.state = CAN_STATE_STOPPED; /* can set bus off now */ @@ -659,6 +661,9 @@ static int peak_usb_set_mode(struct net_device *netdev, enum can_mode mode) struct peak_usb_device *dev = netdev_priv(netdev); int err = 0; + if (!dev->open_time) + return -EINVAL; + switch (mode) { case CAN_MODE_START: err = peak_usb_restart(dev); diff --git a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_core.h index 073b47ff8eee..c8e5e91d7cb5 100644 --- a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_core.h +++ b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_core.h @@ -104,6 +104,7 @@ struct peak_usb_device { struct can_priv can; struct peak_usb_adapter *adapter; unsigned int ctrl_idx; + int open_time; u32 state; struct sk_buff *echo_skb[PCAN_USB_MAX_TX_URBS]; diff --git a/trunk/include/linux/netfilter_ipv6/ip6_tables.h b/trunk/include/linux/netfilter_ipv6/ip6_tables.h index 610208b18c05..5f84c6229dc6 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6_tables.h +++ b/trunk/include/linux/netfilter_ipv6/ip6_tables.h @@ -47,6 +47,15 @@ ip6t_ext_hdr(u8 nexthdr) (nexthdr == IPPROTO_DSTOPTS); } +enum { + IP6T_FH_F_FRAG = (1 << 0), + IP6T_FH_F_AUTH = (1 << 1), +}; + +/* find specified header and get offset to it */ +extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, + int target, unsigned short *fragoff, int *fragflg); + #ifdef CONFIG_COMPAT #include diff --git a/trunk/include/linux/openvswitch.h b/trunk/include/linux/openvswitch.h index d42e174bd0c8..eb1efa54fe84 100644 --- a/trunk/include/linux/openvswitch.h +++ b/trunk/include/linux/openvswitch.h @@ -243,7 +243,6 @@ enum ovs_key_attr { OVS_KEY_ATTR_ICMPV6, /* struct ovs_key_icmpv6 */ OVS_KEY_ATTR_ARP, /* struct ovs_key_arp */ OVS_KEY_ATTR_ND, /* struct ovs_key_nd */ - OVS_KEY_ATTR_SKB_MARK, /* u32 skb mark */ __OVS_KEY_ATTR_MAX }; diff --git a/trunk/include/net/ipv6.h b/trunk/include/net/ipv6.h index acbd8e034310..979bf6c13141 100644 --- a/trunk/include/net/ipv6.h +++ b/trunk/include/net/ipv6.h @@ -630,16 +630,6 @@ extern int ipv6_skip_exthdr(const struct sk_buff *, int start, extern bool ipv6_ext_hdr(u8 nexthdr); -enum { - IP6_FH_F_FRAG = (1 << 0), - IP6_FH_F_AUTH = (1 << 1), - IP6_FH_F_SKIP_RH = (1 << 2), -}; - -/* find specified header and get offset to it */ -extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, - int target, unsigned short *fragoff, int *fragflg); - extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type); extern struct in6_addr *fl6_update_dst(struct flowi6 *fl6, diff --git a/trunk/net/8021q/vlan.c b/trunk/net/8021q/vlan.c index a292e8050ef2..afba51e60310 100644 --- a/trunk/net/8021q/vlan.c +++ b/trunk/net/8021q/vlan.c @@ -242,7 +242,6 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) * hope the underlying device can handle it. */ new_dev->mtu = real_dev->mtu; - new_dev->priv_flags |= (real_dev->priv_flags & IFF_UNICAST_FLT); vlan_dev_priv(new_dev)->vlan_id = vlan_id; vlan_dev_priv(new_dev)->real_dev = real_dev; diff --git a/trunk/net/batman-adv/hard-interface.c b/trunk/net/batman-adv/hard-interface.c index 365ed74f3946..f1d37cd81815 100644 --- a/trunk/net/batman-adv/hard-interface.c +++ b/trunk/net/batman-adv/hard-interface.c @@ -30,6 +30,7 @@ #include "bridge_loop_avoidance.h" #include +#include void batadv_hardif_free_rcu(struct rcu_head *rcu) { @@ -311,7 +312,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, { struct batadv_priv *bat_priv; struct net_device *soft_iface; - __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); + __be16 ethertype = __constant_htons(ETH_P_BATMAN); int ret; if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) diff --git a/trunk/net/batman-adv/packet.h b/trunk/net/batman-adv/packet.h index 1c5454d33f67..cb6405bf755c 100644 --- a/trunk/net/batman-adv/packet.h +++ b/trunk/net/batman-adv/packet.h @@ -20,8 +20,6 @@ #ifndef _NET_BATMAN_ADV_PACKET_H_ #define _NET_BATMAN_ADV_PACKET_H_ -#define BATADV_ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ - enum batadv_packettype { BATADV_IV_OGM = 0x01, BATADV_ICMP = 0x02, diff --git a/trunk/net/batman-adv/send.c b/trunk/net/batman-adv/send.c index c7f702376535..4425af9dad40 100644 --- a/trunk/net/batman-adv/send.c +++ b/trunk/net/batman-adv/send.c @@ -28,6 +28,8 @@ #include "gateway_common.h" #include "originator.h" +#include + static void batadv_send_outstanding_bcast_packet(struct work_struct *work); /* send out an already prepared packet to the given address via the @@ -60,11 +62,11 @@ int batadv_send_skb_packet(struct sk_buff *skb, ethhdr = (struct ethhdr *)skb_mac_header(skb); memcpy(ethhdr->h_source, hard_iface->net_dev->dev_addr, ETH_ALEN); memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); - ethhdr->h_proto = __constant_htons(BATADV_ETH_P_BATMAN); + ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); skb_set_network_header(skb, ETH_HLEN); skb->priority = TC_PRIO_CONTROL; - skb->protocol = __constant_htons(BATADV_ETH_P_BATMAN); + skb->protocol = __constant_htons(ETH_P_BATMAN); skb->dev = hard_iface->net_dev; diff --git a/trunk/net/batman-adv/soft-interface.c b/trunk/net/batman-adv/soft-interface.c index 54800c783f96..6b548fde8e04 100644 --- a/trunk/net/batman-adv/soft-interface.c +++ b/trunk/net/batman-adv/soft-interface.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "unicast.h" #include "bridge_loop_avoidance.h" @@ -146,7 +147,7 @@ static int batadv_interface_tx(struct sk_buff *skb, struct batadv_hard_iface *primary_if = NULL; struct batadv_bcast_packet *bcast_packet; struct vlan_ethhdr *vhdr; - __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); + __be16 ethertype = __constant_htons(ETH_P_BATMAN); static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}; static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, @@ -172,7 +173,7 @@ static int batadv_interface_tx(struct sk_buff *skb, break; /* fall through */ - case BATADV_ETH_P_BATMAN: + case ETH_P_BATMAN: goto dropped; } @@ -302,7 +303,7 @@ void batadv_interface_rx(struct net_device *soft_iface, struct vlan_ethhdr *vhdr; struct batadv_header *batadv_header = (struct batadv_header *)skb->data; short vid __maybe_unused = -1; - __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); + __be16 ethertype = __constant_htons(ETH_P_BATMAN); bool is_bcast; is_bcast = (batadv_header->packet_type == BATADV_BCAST); @@ -325,7 +326,7 @@ void batadv_interface_rx(struct net_device *soft_iface, break; /* fall through */ - case BATADV_ETH_P_BATMAN: + case ETH_P_BATMAN: goto dropped; } diff --git a/trunk/net/ieee802154/6lowpan.c b/trunk/net/ieee802154/6lowpan.c index f651da60f161..6d42c17af96b 100644 --- a/trunk/net/ieee802154/6lowpan.c +++ b/trunk/net/ieee802154/6lowpan.c @@ -1047,8 +1047,7 @@ static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev) goto error; } - /* Send directly if less than the MTU minus the 2 checksum bytes. */ - if (skb->len <= IEEE802154_MTU - IEEE802154_MFR_SIZE) { + if (skb->len <= IEEE802154_MTU) { err = dev_queue_xmit(skb); goto out; } diff --git a/trunk/net/ipv6/exthdrs_core.c b/trunk/net/ipv6/exthdrs_core.c index c5e83fae4df4..e7d756e19d1d 100644 --- a/trunk/net/ipv6/exthdrs_core.c +++ b/trunk/net/ipv6/exthdrs_core.c @@ -155,127 +155,3 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type) return -1; } EXPORT_SYMBOL_GPL(ipv6_find_tlv); - -/* - * find the offset to specified header or the protocol number of last header - * if target < 0. "last header" is transport protocol header, ESP, or - * "No next header". - * - * Note that *offset is used as input/output parameter. an if it is not zero, - * then it must be a valid offset to an inner IPv6 header. This can be used - * to explore inner IPv6 header, eg. ICMPv6 error messages. - * - * If target header is found, its offset is set in *offset and return protocol - * number. Otherwise, return -1. - * - * If the first fragment doesn't contain the final protocol header or - * NEXTHDR_NONE it is considered invalid. - * - * Note that non-1st fragment is special case that "the protocol number - * of last header" is "next header" field in Fragment header. In this case, - * *offset is meaningless and fragment offset is stored in *fragoff if fragoff - * isn't NULL. - * - * if flags is not NULL and it's a fragment, then the frag flag - * IP6_FH_F_FRAG will be set. If it's an AH header, the - * IP6_FH_F_AUTH flag is set and target < 0, then this function will - * stop at the AH header. If IP6_FH_F_SKIP_RH flag was passed, then this - * function will skip all those routing headers, where segements_left was 0. - */ -int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, - int target, unsigned short *fragoff, int *flags) -{ - unsigned int start = skb_network_offset(skb) + sizeof(struct ipv6hdr); - u8 nexthdr = ipv6_hdr(skb)->nexthdr; - unsigned int len; - bool found; - - if (fragoff) - *fragoff = 0; - - if (*offset) { - struct ipv6hdr _ip6, *ip6; - - ip6 = skb_header_pointer(skb, *offset, sizeof(_ip6), &_ip6); - if (!ip6 || (ip6->version != 6)) { - printk(KERN_ERR "IPv6 header not found\n"); - return -EBADMSG; - } - start = *offset + sizeof(struct ipv6hdr); - nexthdr = ip6->nexthdr; - } - len = skb->len - start; - - do { - struct ipv6_opt_hdr _hdr, *hp; - unsigned int hdrlen; - found = (nexthdr == target); - - if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { - if (target < 0) - break; - return -ENOENT; - } - - hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); - if (hp == NULL) - return -EBADMSG; - - if (nexthdr == NEXTHDR_ROUTING) { - struct ipv6_rt_hdr _rh, *rh; - - rh = skb_header_pointer(skb, start, sizeof(_rh), - &_rh); - if (rh == NULL) - return -EBADMSG; - - if (flags && (*flags & IP6_FH_F_SKIP_RH) && - rh->segments_left == 0) - found = false; - } - - if (nexthdr == NEXTHDR_FRAGMENT) { - unsigned short _frag_off; - __be16 *fp; - - if (flags) /* Indicate that this is a fragment */ - *flags |= IP6_FH_F_FRAG; - fp = skb_header_pointer(skb, - start+offsetof(struct frag_hdr, - frag_off), - sizeof(_frag_off), - &_frag_off); - if (fp == NULL) - return -EBADMSG; - - _frag_off = ntohs(*fp) & ~0x7; - if (_frag_off) { - if (target < 0 && - ((!ipv6_ext_hdr(hp->nexthdr)) || - hp->nexthdr == NEXTHDR_NONE)) { - if (fragoff) - *fragoff = _frag_off; - return hp->nexthdr; - } - return -ENOENT; - } - hdrlen = 8; - } else if (nexthdr == NEXTHDR_AUTH) { - if (flags && (*flags & IP6_FH_F_AUTH) && (target < 0)) - break; - hdrlen = (hp->hdrlen + 2) << 2; - } else - hdrlen = ipv6_optlen(hp); - - if (!found) { - nexthdr = hp->nexthdr; - len -= hdrlen; - start += hdrlen; - } - } while (!found); - - *offset = start; - return nexthdr; -} -EXPORT_SYMBOL(ipv6_find_hdr); - diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c index 125a90d6a795..74cadd0719a5 100644 --- a/trunk/net/ipv6/netfilter/ip6_tables.c +++ b/trunk/net/ipv6/netfilter/ip6_tables.c @@ -2271,9 +2271,112 @@ static void __exit ip6_tables_fini(void) unregister_pernet_subsys(&ip6_tables_net_ops); } +/* + * find the offset to specified header or the protocol number of last header + * if target < 0. "last header" is transport protocol header, ESP, or + * "No next header". + * + * Note that *offset is used as input/output parameter. an if it is not zero, + * then it must be a valid offset to an inner IPv6 header. This can be used + * to explore inner IPv6 header, eg. ICMPv6 error messages. + * + * If target header is found, its offset is set in *offset and return protocol + * number. Otherwise, return -1. + * + * If the first fragment doesn't contain the final protocol header or + * NEXTHDR_NONE it is considered invalid. + * + * Note that non-1st fragment is special case that "the protocol number + * of last header" is "next header" field in Fragment header. In this case, + * *offset is meaningless and fragment offset is stored in *fragoff if fragoff + * isn't NULL. + * + * if flags is not NULL and it's a fragment, then the frag flag IP6T_FH_F_FRAG + * will be set. If it's an AH header, the IP6T_FH_F_AUTH flag is set and + * target < 0, then this function will stop at the AH header. + */ +int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, + int target, unsigned short *fragoff, int *flags) +{ + unsigned int start = skb_network_offset(skb) + sizeof(struct ipv6hdr); + u8 nexthdr = ipv6_hdr(skb)->nexthdr; + unsigned int len; + + if (fragoff) + *fragoff = 0; + + if (*offset) { + struct ipv6hdr _ip6, *ip6; + + ip6 = skb_header_pointer(skb, *offset, sizeof(_ip6), &_ip6); + if (!ip6 || (ip6->version != 6)) { + printk(KERN_ERR "IPv6 header not found\n"); + return -EBADMSG; + } + start = *offset + sizeof(struct ipv6hdr); + nexthdr = ip6->nexthdr; + } + len = skb->len - start; + + while (nexthdr != target) { + struct ipv6_opt_hdr _hdr, *hp; + unsigned int hdrlen; + + if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { + if (target < 0) + break; + return -ENOENT; + } + + hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); + if (hp == NULL) + return -EBADMSG; + if (nexthdr == NEXTHDR_FRAGMENT) { + unsigned short _frag_off; + __be16 *fp; + + if (flags) /* Indicate that this is a fragment */ + *flags |= IP6T_FH_F_FRAG; + fp = skb_header_pointer(skb, + start+offsetof(struct frag_hdr, + frag_off), + sizeof(_frag_off), + &_frag_off); + if (fp == NULL) + return -EBADMSG; + + _frag_off = ntohs(*fp) & ~0x7; + if (_frag_off) { + if (target < 0 && + ((!ipv6_ext_hdr(hp->nexthdr)) || + hp->nexthdr == NEXTHDR_NONE)) { + if (fragoff) + *fragoff = _frag_off; + return hp->nexthdr; + } + return -ENOENT; + } + hdrlen = 8; + } else if (nexthdr == NEXTHDR_AUTH) { + if (flags && (*flags & IP6T_FH_F_AUTH) && (target < 0)) + break; + hdrlen = (hp->hdrlen + 2) << 2; + } else + hdrlen = ipv6_optlen(hp); + + nexthdr = hp->nexthdr; + len -= hdrlen; + start += hdrlen; + } + + *offset = start; + return nexthdr; +} + EXPORT_SYMBOL(ip6t_register_table); EXPORT_SYMBOL(ip6t_unregister_table); EXPORT_SYMBOL(ip6t_do_table); +EXPORT_SYMBOL(ipv6_find_hdr); module_init(ip6_tables_init); module_exit(ip6_tables_fini); diff --git a/trunk/net/mac802154/tx.c b/trunk/net/mac802154/tx.c index 4e09d070995a..1a4df39c722e 100644 --- a/trunk/net/mac802154/tx.c +++ b/trunk/net/mac802154/tx.c @@ -85,7 +85,6 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, if (!(priv->phy->channels_supported[page] & (1 << chan))) { WARN_ON(1); - kfree_skb(skb); return NETDEV_TX_OK; } @@ -99,15 +98,13 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, } if (skb_cow_head(skb, priv->hw.extra_tx_headroom)) { - kfree_skb(skb); + dev_kfree_skb(skb); return NETDEV_TX_OK; } work = kzalloc(sizeof(struct xmit_work), GFP_ATOMIC); - if (!work) { - kfree_skb(skb); + if (!work) return NETDEV_TX_BUSY; - } INIT_WORK(&work->work, mac802154_xmit_worker); work->skb = skb; diff --git a/trunk/net/mac802154/wpan.c b/trunk/net/mac802154/wpan.c index 1191039c2b1b..f30f6d4beea1 100644 --- a/trunk/net/mac802154/wpan.c +++ b/trunk/net/mac802154/wpan.c @@ -327,10 +327,8 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) if (chan == MAC802154_CHAN_NONE || page >= WPAN_NUM_PAGES || - chan >= WPAN_NUM_CHANNELS) { - kfree_skb(skb); + chan >= WPAN_NUM_CHANNELS) return NETDEV_TX_OK; - } skb->skb_iif = dev->ifindex; dev->stats.tx_packets++; diff --git a/trunk/net/netfilter/ipvs/ip_vs_core.c b/trunk/net/netfilter/ipvs/ip_vs_core.c index 47edf5a40a59..fb45640dc1fb 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_core.c +++ b/trunk/net/netfilter/ipvs/ip_vs_core.c @@ -942,7 +942,7 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related, /* Fragment header that is before ICMP header tells us that: * it's not an error message since they can't be fragmented. */ - if (ipvsh->flags & IP6_FH_F_FRAG) + if (ipvsh->flags & IP6T_FH_F_FRAG) return NF_DROP; IP_VS_DBG(8, "Outgoing ICMPv6 (%d,%d) %pI6c->%pI6c\n", @@ -1475,7 +1475,7 @@ static int ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, /* Fragment header that is before ICMP header tells us that: * it's not an error message since they can't be fragmented. */ - if (iph->flags & IP6_FH_F_FRAG) + if (iph->flags & IP6T_FH_F_FRAG) return NF_DROP; IP_VS_DBG(8, "Incoming ICMPv6 (%d,%d) %pI6c->%pI6c\n", diff --git a/trunk/net/netfilter/xt_HMARK.c b/trunk/net/netfilter/xt_HMARK.c index 73b73f687c58..1686ca1b53a1 100644 --- a/trunk/net/netfilter/xt_HMARK.c +++ b/trunk/net/netfilter/xt_HMARK.c @@ -167,7 +167,7 @@ hmark_pkt_set_htuple_ipv6(const struct sk_buff *skb, struct hmark_tuple *t, const struct xt_hmark_info *info) { struct ipv6hdr *ip6, _ip6; - int flag = IP6_FH_F_AUTH; + int flag = IP6T_FH_F_AUTH; unsigned int nhoff = 0; u16 fragoff = 0; int nexthdr; @@ -177,7 +177,7 @@ hmark_pkt_set_htuple_ipv6(const struct sk_buff *skb, struct hmark_tuple *t, if (nexthdr < 0) return 0; /* No need to check for icmp errors on fragments */ - if ((flag & IP6_FH_F_FRAG) || (nexthdr != IPPROTO_ICMPV6)) + if ((flag & IP6T_FH_F_FRAG) || (nexthdr != IPPROTO_ICMPV6)) goto noicmp; /* Use inner header in case of ICMP errors */ if (get_inner6_hdr(skb, &nhoff)) { @@ -185,7 +185,7 @@ hmark_pkt_set_htuple_ipv6(const struct sk_buff *skb, struct hmark_tuple *t, if (ip6 == NULL) return -1; /* If AH present, use SPI like in ESP. */ - flag = IP6_FH_F_AUTH; + flag = IP6T_FH_F_AUTH; nexthdr = ipv6_find_hdr(skb, &nhoff, -1, &fragoff, &flag); if (nexthdr < 0) return -1; @@ -201,7 +201,7 @@ hmark_pkt_set_htuple_ipv6(const struct sk_buff *skb, struct hmark_tuple *t, if (t->proto == IPPROTO_ICMPV6) return 0; - if (flag & IP6_FH_F_FRAG) + if (flag & IP6T_FH_F_FRAG) return 0; hmark_set_tuple_ports(skb, nhoff, t, info); diff --git a/trunk/net/openvswitch/actions.c b/trunk/net/openvswitch/actions.c index ac2defeeba83..08114478cb85 100644 --- a/trunk/net/openvswitch/actions.c +++ b/trunk/net/openvswitch/actions.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -163,53 +162,6 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh, *addr = new_addr; } -static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto, - __be32 addr[4], const __be32 new_addr[4]) -{ - int transport_len = skb->len - skb_transport_offset(skb); - - if (l4_proto == IPPROTO_TCP) { - if (likely(transport_len >= sizeof(struct tcphdr))) - inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb, - addr, new_addr, 1); - } else if (l4_proto == IPPROTO_UDP) { - if (likely(transport_len >= sizeof(struct udphdr))) { - struct udphdr *uh = udp_hdr(skb); - - if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) { - inet_proto_csum_replace16(&uh->check, skb, - addr, new_addr, 1); - if (!uh->check) - uh->check = CSUM_MANGLED_0; - } - } - } -} - -static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto, - __be32 addr[4], const __be32 new_addr[4], - bool recalculate_csum) -{ - if (recalculate_csum) - update_ipv6_checksum(skb, l4_proto, addr, new_addr); - - skb->rxhash = 0; - memcpy(addr, new_addr, sizeof(__be32[4])); -} - -static void set_ipv6_tc(struct ipv6hdr *nh, u8 tc) -{ - nh->priority = tc >> 4; - nh->flow_lbl[0] = (nh->flow_lbl[0] & 0x0F) | ((tc & 0x0F) << 4); -} - -static void set_ipv6_fl(struct ipv6hdr *nh, u32 fl) -{ - nh->flow_lbl[0] = (nh->flow_lbl[0] & 0xF0) | (fl & 0x000F0000) >> 16; - nh->flow_lbl[1] = (fl & 0x0000FF00) >> 8; - nh->flow_lbl[2] = fl & 0x000000FF; -} - static void set_ip_ttl(struct sk_buff *skb, struct iphdr *nh, u8 new_ttl) { csum_replace2(&nh->check, htons(nh->ttl << 8), htons(new_ttl << 8)); @@ -243,47 +195,6 @@ static int set_ipv4(struct sk_buff *skb, const struct ovs_key_ipv4 *ipv4_key) return 0; } -static int set_ipv6(struct sk_buff *skb, const struct ovs_key_ipv6 *ipv6_key) -{ - struct ipv6hdr *nh; - int err; - __be32 *saddr; - __be32 *daddr; - - err = make_writable(skb, skb_network_offset(skb) + - sizeof(struct ipv6hdr)); - if (unlikely(err)) - return err; - - nh = ipv6_hdr(skb); - saddr = (__be32 *)&nh->saddr; - daddr = (__be32 *)&nh->daddr; - - if (memcmp(ipv6_key->ipv6_src, saddr, sizeof(ipv6_key->ipv6_src))) - set_ipv6_addr(skb, ipv6_key->ipv6_proto, saddr, - ipv6_key->ipv6_src, true); - - if (memcmp(ipv6_key->ipv6_dst, daddr, sizeof(ipv6_key->ipv6_dst))) { - unsigned int offset = 0; - int flags = IP6_FH_F_SKIP_RH; - bool recalc_csum = true; - - if (ipv6_ext_hdr(nh->nexthdr)) - recalc_csum = ipv6_find_hdr(skb, &offset, - NEXTHDR_ROUTING, NULL, - &flags) != NEXTHDR_ROUTING; - - set_ipv6_addr(skb, ipv6_key->ipv6_proto, daddr, - ipv6_key->ipv6_dst, recalc_csum); - } - - set_ipv6_tc(nh, ipv6_key->ipv6_tclass); - set_ipv6_fl(nh, ntohl(ipv6_key->ipv6_label)); - nh->hop_limit = ipv6_key->ipv6_hlimit; - - return 0; -} - /* Must follow make_writable() since that can move the skb data. */ static void set_tp_port(struct sk_buff *skb, __be16 *port, __be16 new_port, __sum16 *check) @@ -428,10 +339,6 @@ static int execute_set_action(struct sk_buff *skb, skb->priority = nla_get_u32(nested_attr); break; - case OVS_KEY_ATTR_SKB_MARK: - skb->mark = nla_get_u32(nested_attr); - break; - case OVS_KEY_ATTR_ETHERNET: err = set_eth_addr(skb, nla_data(nested_attr)); break; @@ -440,10 +347,6 @@ static int execute_set_action(struct sk_buff *skb, err = set_ipv4(skb, nla_data(nested_attr)); break; - case OVS_KEY_ATTR_IPV6: - err = set_ipv6(skb, nla_data(nested_attr)); - break; - case OVS_KEY_ATTR_TCP: err = set_tcp(skb, nla_data(nested_attr)); break; diff --git a/trunk/net/openvswitch/datapath.c b/trunk/net/openvswitch/datapath.c index f996db343247..4c4b62ccc7d7 100644 --- a/trunk/net/openvswitch/datapath.c +++ b/trunk/net/openvswitch/datapath.c @@ -208,7 +208,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb) int error; int key_len; - stats = this_cpu_ptr(dp->stats_percpu); + stats = per_cpu_ptr(dp->stats_percpu, smp_processor_id()); /* Extract flow from 'skb' into 'key'. */ error = ovs_flow_extract(skb, p->port_no, &key, &key_len); @@ -282,7 +282,7 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb, return 0; err: - stats = this_cpu_ptr(dp->stats_percpu); + stats = per_cpu_ptr(dp->stats_percpu, smp_processor_id()); u64_stats_update_begin(&stats->sync); stats->n_lost++; @@ -479,10 +479,8 @@ static int validate_set(const struct nlattr *a, switch (key_type) { const struct ovs_key_ipv4 *ipv4_key; - const struct ovs_key_ipv6 *ipv6_key; case OVS_KEY_ATTR_PRIORITY: - case OVS_KEY_ATTR_SKB_MARK: case OVS_KEY_ATTR_ETHERNET: break; @@ -502,25 +500,6 @@ static int validate_set(const struct nlattr *a, break; - case OVS_KEY_ATTR_IPV6: - if (flow_key->eth.type != htons(ETH_P_IPV6)) - return -EINVAL; - - if (!flow_key->ip.proto) - return -EINVAL; - - ipv6_key = nla_data(ovs_key); - if (ipv6_key->ipv6_proto != flow_key->ip.proto) - return -EINVAL; - - if (ipv6_key->ipv6_frag != flow_key->ip.frag) - return -EINVAL; - - if (ntohl(ipv6_key->ipv6_label) & 0xFFF00000) - return -EINVAL; - - break; - case OVS_KEY_ATTR_TCP: if (flow_key->ip.proto != IPPROTO_TCP) return -EINVAL; @@ -696,7 +675,6 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) goto err_flow_free; err = ovs_flow_metadata_from_nlattrs(&flow->key.phy.priority, - &flow->key.phy.skb_mark, &flow->key.phy.in_port, a[OVS_PACKET_ATTR_KEY]); if (err) @@ -716,7 +694,6 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) OVS_CB(packet)->flow = flow; packet->priority = flow->key.phy.priority; - packet->mark = flow->key.phy.skb_mark; rcu_read_lock(); dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); diff --git a/trunk/net/openvswitch/flow.c b/trunk/net/openvswitch/flow.c index c3294cebc4f2..733cbf49ed1f 100644 --- a/trunk/net/openvswitch/flow.c +++ b/trunk/net/openvswitch/flow.c @@ -604,7 +604,6 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key, key->phy.priority = skb->priority; key->phy.in_port = in_port; - key->phy.skb_mark = skb->mark; skb_reset_mac_header(skb); @@ -690,8 +689,7 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key, } } - } else if ((key->eth.type == htons(ETH_P_ARP) || - key->eth.type == htons(ETH_P_RARP)) && arphdr_ok(skb)) { + } else if (key->eth.type == htons(ETH_P_ARP) && arphdr_ok(skb)) { struct arp_eth_header *arp; arp = (struct arp_eth_header *)skb_network_header(skb); @@ -804,7 +802,6 @@ const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = { [OVS_KEY_ATTR_ENCAP] = -1, [OVS_KEY_ATTR_PRIORITY] = sizeof(u32), [OVS_KEY_ATTR_IN_PORT] = sizeof(u32), - [OVS_KEY_ATTR_SKB_MARK] = sizeof(u32), [OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet), [OVS_KEY_ATTR_VLAN] = sizeof(__be16), [OVS_KEY_ATTR_ETHERTYPE] = sizeof(__be16), @@ -990,10 +987,6 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, } else { swkey->phy.in_port = DP_MAX_PORTS; } - if (attrs & (1 << OVS_KEY_ATTR_SKB_MARK)) { - swkey->phy.skb_mark = nla_get_u32(a[OVS_KEY_ATTR_SKB_MARK]); - attrs &= ~(1 << OVS_KEY_ATTR_SKB_MARK); - } /* Data attributes. */ if (!(attrs & (1 << OVS_KEY_ATTR_ETHERNET))) @@ -1093,8 +1086,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, if (err) return err; } - } else if (swkey->eth.type == htons(ETH_P_ARP) || - swkey->eth.type == htons(ETH_P_RARP)) { + } else if (swkey->eth.type == htons(ETH_P_ARP)) { const struct ovs_key_arp *arp_key; if (!(attrs & (1 << OVS_KEY_ATTR_ARP))) @@ -1121,8 +1113,6 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, /** * ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key. - * @priority: receives the skb priority - * @mark: receives the skb mark * @in_port: receives the extracted input port. * @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute * sequence. @@ -1132,7 +1122,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, * get the metadata, that is, the parts of the flow key that cannot be * extracted from the packet itself. */ -int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port, +int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, const struct nlattr *attr) { const struct nlattr *nla; @@ -1140,7 +1130,6 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port, *in_port = DP_MAX_PORTS; *priority = 0; - *mark = 0; nla_for_each_nested(nla, attr, rem) { int type = nla_type(nla); @@ -1159,10 +1148,6 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port, return -EINVAL; *in_port = nla_get_u32(nla); break; - - case OVS_KEY_ATTR_SKB_MARK: - *mark = nla_get_u32(nla); - break; } } } @@ -1184,10 +1169,6 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) goto nla_put_failure; - if (swkey->phy.skb_mark && - nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, swkey->phy.skb_mark)) - goto nla_put_failure; - nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key)); if (!nla) goto nla_put_failure; @@ -1241,8 +1222,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) ipv6_key->ipv6_tclass = swkey->ip.tos; ipv6_key->ipv6_hlimit = swkey->ip.ttl; ipv6_key->ipv6_frag = swkey->ip.frag; - } else if (swkey->eth.type == htons(ETH_P_ARP) || - swkey->eth.type == htons(ETH_P_RARP)) { + } else if (swkey->eth.type == htons(ETH_P_ARP)) { struct ovs_key_arp *arp_key; nla = nla_reserve(skb, OVS_KEY_ATTR_ARP, sizeof(*arp_key)); diff --git a/trunk/net/openvswitch/flow.h b/trunk/net/openvswitch/flow.h index a7bb60ff3b5b..14a324eb017b 100644 --- a/trunk/net/openvswitch/flow.h +++ b/trunk/net/openvswitch/flow.h @@ -43,7 +43,6 @@ struct sw_flow_actions { struct sw_flow_key { struct { u32 priority; /* Packet QoS priority. */ - u32 skb_mark; /* SKB mark. */ u16 in_port; /* Input switch port (or DP_MAX_PORTS). */ } phy; struct { @@ -145,7 +144,6 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies); * ------ --- ------ ----- * OVS_KEY_ATTR_PRIORITY 4 -- 4 8 * OVS_KEY_ATTR_IN_PORT 4 -- 4 8 - * OVS_KEY_ATTR_SKB_MARK 4 -- 4 8 * OVS_KEY_ATTR_ETHERNET 12 -- 4 16 * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (outer VLAN ethertype) * OVS_KEY_ATTR_8021Q 4 -- 4 8 @@ -155,14 +153,14 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies); * OVS_KEY_ATTR_ICMPV6 2 2 4 8 * OVS_KEY_ATTR_ND 28 -- 4 32 * ------------------------------------------------- - * total 152 + * total 144 */ -#define FLOW_BUFSIZE 152 +#define FLOW_BUFSIZE 144 int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *); int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, const struct nlattr *); -int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port, +int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, const struct nlattr *); #define MAX_ACTIONS_BUFSIZE (16 * 1024) diff --git a/trunk/net/openvswitch/vport-netdev.c b/trunk/net/openvswitch/vport-netdev.c index a9327e2e48ce..a9033481fa5e 100644 --- a/trunk/net/openvswitch/vport-netdev.c +++ b/trunk/net/openvswitch/vport-netdev.c @@ -114,15 +114,6 @@ static struct vport *netdev_create(const struct vport_parms *parms) return ERR_PTR(err); } -static void free_port_rcu(struct rcu_head *rcu) -{ - struct netdev_vport *netdev_vport = container_of(rcu, - struct netdev_vport, rcu); - - dev_put(netdev_vport->dev); - ovs_vport_free(vport_from_priv(netdev_vport)); -} - static void netdev_destroy(struct vport *vport) { struct netdev_vport *netdev_vport = netdev_vport_priv(vport); @@ -131,7 +122,10 @@ static void netdev_destroy(struct vport *vport) netdev_rx_handler_unregister(netdev_vport->dev); dev_set_promiscuity(netdev_vport->dev, -1); - call_rcu(&netdev_vport->rcu, free_port_rcu); + synchronize_rcu(); + + dev_put(netdev_vport->dev); + ovs_vport_free(vport); } const char *ovs_netdev_get_name(const struct vport *vport) diff --git a/trunk/net/openvswitch/vport-netdev.h b/trunk/net/openvswitch/vport-netdev.h index 6478079b3417..f7072a25c604 100644 --- a/trunk/net/openvswitch/vport-netdev.h +++ b/trunk/net/openvswitch/vport-netdev.h @@ -20,15 +20,12 @@ #define VPORT_NETDEV_H 1 #include -#include #include "vport.h" struct vport *ovs_netdev_get_vport(struct net_device *dev); struct netdev_vport { - struct rcu_head rcu; - struct net_device *dev; }; diff --git a/trunk/net/openvswitch/vport.c b/trunk/net/openvswitch/vport.c index 70af0bedbac4..03779e8a2622 100644 --- a/trunk/net/openvswitch/vport.c +++ b/trunk/net/openvswitch/vport.c @@ -333,7 +333,8 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb) { struct vport_percpu_stats *stats; - stats = this_cpu_ptr(vport->percpu_stats); + stats = per_cpu_ptr(vport->percpu_stats, smp_processor_id()); + u64_stats_update_begin(&stats->sync); stats->rx_packets++; stats->rx_bytes += skb->len; @@ -358,7 +359,7 @@ int ovs_vport_send(struct vport *vport, struct sk_buff *skb) if (likely(sent)) { struct vport_percpu_stats *stats; - stats = this_cpu_ptr(vport->percpu_stats); + stats = per_cpu_ptr(vport->percpu_stats, smp_processor_id()); u64_stats_update_begin(&stats->sync); stats->tx_packets++; diff --git a/trunk/net/sctp/ipv6.c b/trunk/net/sctp/ipv6.c index f3f0f4dc31dd..ea14cb445295 100644 --- a/trunk/net/sctp/ipv6.c +++ b/trunk/net/sctp/ipv6.c @@ -345,7 +345,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, } out: - if (!IS_ERR_OR_NULL(dst)) { + if (!IS_ERR(dst)) { struct rt6_info *rt; rt = (struct rt6_info *)dst; t->dst = dst;