diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-24 21:01:50 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-24 21:01:50 +0400 |
commit | 3c4cfadef6a1665d9cd02a543782d03d3e6740c6 (patch) | |
tree | 3df72faaacd494d5ac8c9668df4f529b1b5e4457 /net/batman-adv/unicast.c | |
parent | e017507f37d5cb8b541df165a824958bc333bec3 (diff) | |
parent | 320f5ea0cedc08ef65d67e056bcb9d181386ef2c (diff) | |
download | linux-3c4cfadef6a1665d9cd02a543782d03d3e6740c6.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking changes from David S Miller:
1) Remove the ipv4 routing cache. Now lookups go directly into the FIB
trie and use prebuilt routes cached there.
No more garbage collection, no more rDOS attacks on the routing
cache. Instead we now get predictable and consistent performance,
no matter what the pattern of traffic we service.
This has been almost 2 years in the making. Special thanks to
Julian Anastasov, Eric Dumazet, Steffen Klassert, and others who
have helped along the way.
I'm sure that with a change of this magnitude there will be some
kind of fallout, but such things ought the be simple to fix at this
point. Luckily I'm not European so I'll be around all of August to
fix things :-)
The major stages of this work here are each fronted by a forced
merge commit whose commit message contains a top-level description
of the motivations and implementation issues.
2) Pre-demux of established ipv4 TCP sockets, saves a route demux on
input.
3) TCP SYN/ACK performance tweaks from Eric Dumazet.
4) Add namespace support for netfilter L4 conntrack helpers, from Gao
Feng.
5) Add config mechanism for Energy Efficient Ethernet to ethtool, from
Yuval Mintz.
6) Remove quadratic behavior from /proc/net/unix, from Eric Dumazet.
7) Support for connection tracker helpers in userspace, from Pablo
Neira Ayuso.
8) Allow userspace driven TX load balancing functions in TEAM driver,
from Jiri Pirko.
9) Kill off NLMSG_PUT and RTA_PUT macros, more gross stuff with
embedded gotos.
10) TCP Small Queues, essentially minimize the amount of TCP data queued
up in the packet scheduler layer. Whereas the existing BQL (Byte
Queue Limits) limits the pkt_sched --> netdevice queuing levels,
this controls the TCP --> pkt_sched queueing levels.
From Eric Dumazet.
11) Reduce the number of get_page/put_page ops done on SKB fragments,
from Alexander Duyck.
12) Implement protection against blind resets in TCP (RFC 5961), from
Eric Dumazet.
13) Support the client side of TCP Fast Open, basically the ability to
send data in the SYN exchange, from Yuchung Cheng.
Basically, the sender queues up data with a sendmsg() call using
MSG_FASTOPEN, then they do the connect() which emits the queued up
fastopen data.
14) Avoid all the problems we get into in TCP when timers or PMTU events
hit a locked socket. The TCP Small Queues changes added a
tcp_release_cb() that allows us to queue work up to the
release_sock() caller, and that's what we use here too. From Eric
Dumazet.
15) Zero copy on TX support for TUN driver, from Michael S. Tsirkin.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1870 commits)
genetlink: define lockdep_genl_is_held() when CONFIG_LOCKDEP
r8169: revert "add byte queue limit support".
ipv4: Change rt->rt_iif encoding.
net: Make skb->skb_iif always track skb->dev
ipv4: Prepare for change of rt->rt_iif encoding.
ipv4: Remove all RTCF_DIRECTSRC handliing.
ipv4: Really ignore ICMP address requests/replies.
decnet: Don't set RTCF_DIRECTSRC.
net/ipv4/ip_vti.c: Fix __rcu warnings detected by sparse.
ipv4: Remove redundant assignment
rds: set correct msg_namelen
openvswitch: potential NULL deref in sample()
tcp: dont drop MTU reduction indications
bnx2x: Add new 57840 device IDs
tcp: avoid oops in tcp_metrics and reset tcpm_stamp
niu: Change niu_rbr_fill() to use unlikely() to check niu_rbr_add_page() return value
niu: Fix to check for dma mapping errors.
net: Fix references to out-of-scope variables in put_cmsg_compat()
net: ethernet: davinci_emac: add pm_runtime support
net: ethernet: davinci_emac: Remove unnecessary #include
...
Diffstat (limited to 'net/batman-adv/unicast.c')
-rw-r--r-- | net/batman-adv/unicast.c | 179 |
1 files changed, 93 insertions, 86 deletions
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 74175c210858..00164645b3f7 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: +/* Copyright (C) 2010-2012 B.A.T.M.A.N. contributors: * * Andreas Langer * @@ -16,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA - * */ #include "main.h" @@ -31,19 +29,20 @@ #include "hard-interface.h" -static struct sk_buff *frag_merge_packet(struct list_head *head, - struct frag_packet_list_entry *tfp, - struct sk_buff *skb) +static struct sk_buff * +batadv_frag_merge_packet(struct list_head *head, + struct batadv_frag_packet_list_entry *tfp, + struct sk_buff *skb) { - struct unicast_frag_packet *up = - (struct unicast_frag_packet *)skb->data; + struct batadv_unicast_frag_packet *up; struct sk_buff *tmp_skb; - struct unicast_packet *unicast_packet; + struct batadv_unicast_packet *unicast_packet; int hdr_len = sizeof(*unicast_packet); int uni_diff = sizeof(*up) - hdr_len; + up = (struct batadv_unicast_frag_packet *)skb->data; /* set skb to the first part and tmp_skb to the second part */ - if (up->flags & UNI_FRAG_HEAD) { + if (up->flags & BATADV_UNI_FRAG_HEAD) { tmp_skb = tfp->skb; } else { tmp_skb = skb; @@ -66,8 +65,9 @@ static struct sk_buff *frag_merge_packet(struct list_head *head, kfree_skb(tmp_skb); memmove(skb->data + uni_diff, skb->data, hdr_len); - unicast_packet = (struct unicast_packet *)skb_pull(skb, uni_diff); - unicast_packet->header.packet_type = BAT_UNICAST; + unicast_packet = (struct batadv_unicast_packet *)skb_pull(skb, + uni_diff); + unicast_packet->header.packet_type = BATADV_UNICAST; return skb; @@ -77,11 +77,13 @@ err: return NULL; } -static void frag_create_entry(struct list_head *head, struct sk_buff *skb) +static void batadv_frag_create_entry(struct list_head *head, + struct sk_buff *skb) { - struct frag_packet_list_entry *tfp; - struct unicast_frag_packet *up = - (struct unicast_frag_packet *)skb->data; + struct batadv_frag_packet_list_entry *tfp; + struct batadv_unicast_frag_packet *up; + + up = (struct batadv_unicast_frag_packet *)skb->data; /* free and oldest packets stand at the end */ tfp = list_entry((head)->prev, typeof(*tfp), list); @@ -93,15 +95,15 @@ static void frag_create_entry(struct list_head *head, struct sk_buff *skb) return; } -static int frag_create_buffer(struct list_head *head) +static int batadv_frag_create_buffer(struct list_head *head) { int i; - struct frag_packet_list_entry *tfp; + struct batadv_frag_packet_list_entry *tfp; - for (i = 0; i < FRAG_BUFFER_SIZE; i++) { + for (i = 0; i < BATADV_FRAG_BUFFER_SIZE; i++) { tfp = kmalloc(sizeof(*tfp), GFP_ATOMIC); if (!tfp) { - frag_list_free(head); + batadv_frag_list_free(head); return -ENOMEM; } tfp->skb = NULL; @@ -113,14 +115,15 @@ static int frag_create_buffer(struct list_head *head) return 0; } -static struct frag_packet_list_entry *frag_search_packet(struct list_head *head, - const struct unicast_frag_packet *up) +static struct batadv_frag_packet_list_entry * +batadv_frag_search_packet(struct list_head *head, + const struct batadv_unicast_frag_packet *up) { - struct frag_packet_list_entry *tfp; - struct unicast_frag_packet *tmp_up = NULL; + struct batadv_frag_packet_list_entry *tfp; + struct batadv_unicast_frag_packet *tmp_up = NULL; uint16_t search_seqno; - if (up->flags & UNI_FRAG_HEAD) + if (up->flags & BATADV_UNI_FRAG_HEAD) search_seqno = ntohs(up->seqno)+1; else search_seqno = ntohs(up->seqno)-1; @@ -133,12 +136,12 @@ static struct frag_packet_list_entry *frag_search_packet(struct list_head *head, if (tfp->seqno == ntohs(up->seqno)) goto mov_tail; - tmp_up = (struct unicast_frag_packet *)tfp->skb->data; + tmp_up = (struct batadv_unicast_frag_packet *)tfp->skb->data; if (tfp->seqno == search_seqno) { - if ((tmp_up->flags & UNI_FRAG_HEAD) != - (up->flags & UNI_FRAG_HEAD)) + if ((tmp_up->flags & BATADV_UNI_FRAG_HEAD) != + (up->flags & BATADV_UNI_FRAG_HEAD)) return tfp; else goto mov_tail; @@ -151,9 +154,9 @@ mov_tail: return NULL; } -void frag_list_free(struct list_head *head) +void batadv_frag_list_free(struct list_head *head) { - struct frag_packet_list_entry *pf, *tmp_pf; + struct batadv_frag_packet_list_entry *pf, *tmp_pf; if (!list_empty(head)) { @@ -172,64 +175,66 @@ void frag_list_free(struct list_head *head) * or the skb could be reassembled (skb_new will point to the new packet and * skb was freed) */ -int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct sk_buff **new_skb) +int batadv_frag_reassemble_skb(struct sk_buff *skb, + struct batadv_priv *bat_priv, + struct sk_buff **new_skb) { - struct orig_node *orig_node; - struct frag_packet_list_entry *tmp_frag_entry; + struct batadv_orig_node *orig_node; + struct batadv_frag_packet_list_entry *tmp_frag_entry; int ret = NET_RX_DROP; - struct unicast_frag_packet *unicast_packet = - (struct unicast_frag_packet *)skb->data; + struct batadv_unicast_frag_packet *unicast_packet; + unicast_packet = (struct batadv_unicast_frag_packet *)skb->data; *new_skb = NULL; - orig_node = orig_hash_find(bat_priv, unicast_packet->orig); + orig_node = batadv_orig_hash_find(bat_priv, unicast_packet->orig); if (!orig_node) goto out; orig_node->last_frag_packet = jiffies; if (list_empty(&orig_node->frag_list) && - frag_create_buffer(&orig_node->frag_list)) { + batadv_frag_create_buffer(&orig_node->frag_list)) { pr_debug("couldn't create frag buffer\n"); goto out; } - tmp_frag_entry = frag_search_packet(&orig_node->frag_list, - unicast_packet); + tmp_frag_entry = batadv_frag_search_packet(&orig_node->frag_list, + unicast_packet); if (!tmp_frag_entry) { - frag_create_entry(&orig_node->frag_list, skb); + batadv_frag_create_entry(&orig_node->frag_list, skb); ret = NET_RX_SUCCESS; goto out; } - *new_skb = frag_merge_packet(&orig_node->frag_list, tmp_frag_entry, - skb); + *new_skb = batadv_frag_merge_packet(&orig_node->frag_list, + tmp_frag_entry, skb); /* if not, merge failed */ if (*new_skb) ret = NET_RX_SUCCESS; out: if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); return ret; } -int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct hard_iface *hard_iface, const uint8_t dstaddr[]) +int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv, + struct batadv_hard_iface *hard_iface, + const uint8_t dstaddr[]) { - struct unicast_packet tmp_uc, *unicast_packet; - struct hard_iface *primary_if; + struct batadv_unicast_packet tmp_uc, *unicast_packet; + struct batadv_hard_iface *primary_if; struct sk_buff *frag_skb; - struct unicast_frag_packet *frag1, *frag2; + struct batadv_unicast_frag_packet *frag1, *frag2; int uc_hdr_len = sizeof(*unicast_packet); int ucf_hdr_len = sizeof(*frag1); int data_len = skb->len - uc_hdr_len; int large_tail = 0, ret = NET_RX_DROP; uint16_t seqno; - primary_if = primary_if_get_selected(bat_priv); + primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto dropped; @@ -238,38 +243,38 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, goto dropped; skb_reserve(frag_skb, ucf_hdr_len); - unicast_packet = (struct unicast_packet *)skb->data; + unicast_packet = (struct batadv_unicast_packet *)skb->data; memcpy(&tmp_uc, unicast_packet, uc_hdr_len); skb_split(skb, frag_skb, data_len / 2 + uc_hdr_len); - if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || - my_skb_head_push(frag_skb, ucf_hdr_len) < 0) + if (batadv_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || + batadv_skb_head_push(frag_skb, ucf_hdr_len) < 0) goto drop_frag; - frag1 = (struct unicast_frag_packet *)skb->data; - frag2 = (struct unicast_frag_packet *)frag_skb->data; + frag1 = (struct batadv_unicast_frag_packet *)skb->data; + frag2 = (struct batadv_unicast_frag_packet *)frag_skb->data; memcpy(frag1, &tmp_uc, sizeof(tmp_uc)); frag1->header.ttl--; - frag1->header.version = COMPAT_VERSION; - frag1->header.packet_type = BAT_UNICAST_FRAG; + frag1->header.version = BATADV_COMPAT_VERSION; + frag1->header.packet_type = BATADV_UNICAST_FRAG; memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN); memcpy(frag2, frag1, sizeof(*frag2)); if (data_len & 1) - large_tail = UNI_FRAG_LARGETAIL; + large_tail = BATADV_UNI_FRAG_LARGETAIL; - frag1->flags = UNI_FRAG_HEAD | large_tail; + frag1->flags = BATADV_UNI_FRAG_HEAD | large_tail; frag2->flags = large_tail; seqno = atomic_add_return(2, &hard_iface->frag_seqno); frag1->seqno = htons(seqno - 1); frag2->seqno = htons(seqno); - send_skb_packet(skb, hard_iface, dstaddr); - send_skb_packet(frag_skb, hard_iface, dstaddr); + batadv_send_skb_packet(skb, hard_iface, dstaddr); + batadv_send_skb_packet(frag_skb, hard_iface, dstaddr); ret = NET_RX_SUCCESS; goto out; @@ -279,52 +284,53 @@ dropped: kfree_skb(skb); out: if (primary_if) - hardif_free_ref(primary_if); + batadv_hardif_free_ref(primary_if); return ret; } -int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) +int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv) { struct ethhdr *ethhdr = (struct ethhdr *)skb->data; - struct unicast_packet *unicast_packet; - struct orig_node *orig_node; - struct neigh_node *neigh_node; + struct batadv_unicast_packet *unicast_packet; + struct batadv_orig_node *orig_node; + struct batadv_neigh_node *neigh_node; int data_len = skb->len; int ret = 1; + unsigned int dev_mtu; /* get routing information */ if (is_multicast_ether_addr(ethhdr->h_dest)) { - orig_node = gw_get_selected_orig(bat_priv); + orig_node = batadv_gw_get_selected_orig(bat_priv); if (orig_node) goto find_router; } /* check for tt host - increases orig_node refcount. - * returns NULL in case of AP isolation */ - orig_node = transtable_search(bat_priv, ethhdr->h_source, - ethhdr->h_dest); + * returns NULL in case of AP isolation + */ + orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source, + ethhdr->h_dest); find_router: - /** - * find_router(): + /* find_router(): * - if orig_node is NULL it returns NULL * - increases neigh_nodes refcount if found. */ - neigh_node = find_router(bat_priv, orig_node, NULL); + neigh_node = batadv_find_router(bat_priv, orig_node, NULL); if (!neigh_node) goto out; - if (my_skb_head_push(skb, sizeof(*unicast_packet)) < 0) + if (batadv_skb_head_push(skb, sizeof(*unicast_packet)) < 0) goto out; - unicast_packet = (struct unicast_packet *)skb->data; + unicast_packet = (struct batadv_unicast_packet *)skb->data; - unicast_packet->header.version = COMPAT_VERSION; + unicast_packet->header.version = BATADV_COMPAT_VERSION; /* batman packet type: unicast */ - unicast_packet->header.packet_type = BAT_UNICAST; + unicast_packet->header.packet_type = BATADV_UNICAST; /* set unicast ttl */ - unicast_packet->header.ttl = TTL; + unicast_packet->header.ttl = BATADV_TTL; /* copy the destination for faster routing */ memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); /* set the destination tt version number */ @@ -336,28 +342,29 @@ find_router: * try to reroute it because the ttvn contained in the header is less * than the current one */ - if (tt_global_client_is_roaming(bat_priv, ethhdr->h_dest)) + if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest)) unicast_packet->ttvn = unicast_packet->ttvn - 1; + dev_mtu = neigh_node->if_incoming->net_dev->mtu; if (atomic_read(&bat_priv->fragmentation) && - data_len + sizeof(*unicast_packet) > - neigh_node->if_incoming->net_dev->mtu) { + data_len + sizeof(*unicast_packet) > dev_mtu) { /* send frag skb decreases ttl */ unicast_packet->header.ttl++; - ret = frag_send_skb(skb, bat_priv, - neigh_node->if_incoming, neigh_node->addr); + ret = batadv_frag_send_skb(skb, bat_priv, + neigh_node->if_incoming, + neigh_node->addr); goto out; } - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); + batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); ret = 0; goto out; out: if (neigh_node) - neigh_node_free_ref(neigh_node); + batadv_neigh_node_free_ref(neigh_node); if (orig_node) - orig_node_free_ref(orig_node); + batadv_orig_node_free_ref(orig_node); if (ret == 1) kfree_skb(skb); return ret; |