History

net: core: move push MPLS functionality from OvS to core helper

Open vSwitch provides code to push an MPLS header to a packet. In preparation for supporting this in TC, move the push code to an skb helper that can be reused.

John Hurley committed 7 years ago

Commit 8822e271 parent af144a93 files · +69 −27Browse files

Unified · Split

3 files
  1. include/linux/skbuff.h +1 −0
  2. net/core/skbuff.c +64 −0
  3. net/openvswitch/actions.c +4 −27
include/linux/skbuff.h+1−0
@@ -3447,6 +3447,7 @@ int skb_ensure_writable(struct sk_buff *skb, int write_len); · 3446 unmodified lines
3447int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci);3447int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci);
3448int skb_vlan_pop(struct sk_buff *skb);3448int skb_vlan_pop(struct sk_buff *skb);
3449int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci);3449int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci);
3450int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto);
3450struct sk_buff *pskb_extract(struct sk_buff *skb, int off, int to_copy,3451struct sk_buff *pskb_extract(struct sk_buff *skb, int off, int to_copy,
3451 gfp_t gfp);3452 gfp_t gfp);
3452 3453
net/core/skbuff.c+64−0
@@ -66,6 +66,7 @@ · 65 unmodified lines
66#include <net/checksum.h>66#include <net/checksum.h>
67#include <net/ip6_checksum.h>67#include <net/ip6_checksum.h>
68#include <net/xfrm.h>68#include <net/xfrm.h>
69#include <net/mpls.h>
69 70
70#include <linux/uaccess.h>71#include <linux/uaccess.h>
71#include <trace/events/skb.h>72#include <trace/events/skb.h>
@@ -5425,6 +5426,69 @@ int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci) · 5353 unmodified lines
5425}5426}
5426EXPORT_SYMBOL(skb_vlan_push);5427EXPORT_SYMBOL(skb_vlan_push);
5427 5428
5429/* Update the ethertype of hdr and the skb csum value if required. */
5430static void skb_mod_eth_type(struct sk_buff *skb, struct ethhdr *hdr,
5431 __be16 ethertype)
5432{
5433 if (skb->ip_summed == CHECKSUM_COMPLETE) {
5434 __be16 diff[] = { ~hdr->h_proto, ethertype };
5435
5436 skb->csum = csum_partial((char *)diff, sizeof(diff), skb->csum);
5437 }
5438
5439 hdr->h_proto = ethertype;
5440}
5441
5442/**
5443 * skb_mpls_push() - push a new MPLS header after the mac header
5444 *
5445 * @skb: buffer
5446 * @mpls_lse: MPLS label stack entry to push
5447 * @mpls_proto: ethertype of the new MPLS header (expects 0x8847 or 0x8848)
5448 *
5449 * Expects skb->data at mac header.
5450 *
5451 * Returns 0 on success, -errno otherwise.
5452 */
5453int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto)
5454{
5455 struct mpls_shim_hdr *lse;
5456 int err;
5457
5458 if (unlikely(!eth_p_mpls(mpls_proto)))
5459 return -EINVAL;
5460
5461 /* Networking stack does not allow simultaneous Tunnel and MPLS GSO. */
5462 if (skb->encapsulation)
5463 return -EINVAL;
5464
5465 err = skb_cow_head(skb, MPLS_HLEN);
5466 if (unlikely(err))
5467 return err;
5468
5469 if (!skb->inner_protocol) {
5470 skb_set_inner_network_header(skb, skb->mac_len);
5471 skb_set_inner_protocol(skb, skb->protocol);
5472 }
5473
5474 skb_push(skb, MPLS_HLEN);
5475 memmove(skb_mac_header(skb) - MPLS_HLEN, skb_mac_header(skb),
5476 skb->mac_len);
5477 skb_reset_mac_header(skb);
5478 skb_set_network_header(skb, skb->mac_len);
5479
5480 lse = mpls_hdr(skb);
5481 lse->label_stack_entry = mpls_lse;
5482 skb_postpush_rcsum(skb, lse, MPLS_HLEN);
5483
5484 if (skb->dev && skb->dev->type == ARPHRD_ETHER)
5485 skb_mod_eth_type(skb, eth_hdr(skb), mpls_proto);
5486 skb->protocol = mpls_proto;
5487
5488 return 0;
5489}
5490EXPORT_SYMBOL_GPL(skb_mpls_push);
5491
5428/**5492/**
5429 * alloc_skb_with_frags - allocate skb with page frags5493 * alloc_skb_with_frags - allocate skb with page frags
5430 *5494 *
net/openvswitch/actions.c+4−27
@@ -175,34 +175,11 @@ static void update_ethertype(struct sk_buff *skb, struct ethhdr *hdr, · 174 unmodified lines
175static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,175static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
176 const struct ovs_action_push_mpls *mpls)176 const struct ovs_action_push_mpls *mpls)
177{177{
178 struct mpls_shim_hdr *new_mpls_lse;178 int err;
179
180 /* Networking stack do not allow simultaneous Tunnel and MPLS GSO. */
181 if (skb->encapsulation)
182 return -ENOTSUPP;
183
184 if (skb_cow_head(skb, MPLS_HLEN) < 0)
185 return -ENOMEM;
186
187 if (!skb->inner_protocol) {
188 skb_set_inner_network_header(skb, skb->mac_len);
189 skb_set_inner_protocol(skb, skb->protocol);
190 }
191
192 skb_push(skb, MPLS_HLEN);
193 memmove(skb_mac_header(skb) - MPLS_HLEN, skb_mac_header(skb),
194 skb->mac_len);
195 skb_reset_mac_header(skb);
196 skb_set_network_header(skb, skb->mac_len);
197
198 new_mpls_lse = mpls_hdr(skb);
199 new_mpls_lse->label_stack_entry = mpls->mpls_lse;
200
201 skb_postpush_rcsum(skb, new_mpls_lse, MPLS_HLEN);
202 179
203 if (ovs_key_mac_proto(key) == MAC_PROTO_ETHERNET)180 err = skb_mpls_push(skb, mpls->mpls_lse, mpls->mpls_ethertype);
204 update_ethertype(skb, eth_hdr(skb), mpls->mpls_ethertype);181 if (err)
205 skb->protocol = mpls->mpls_ethertype;182 return err;
206 183
207 invalidate_flow_key(key);184 invalidate_flow_key(key);
208 return 0;185 return 0;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t