@@ -16,6 +16,7 @@
#include <linux/if_ether.h>
#include <linux/netdevice.h>
+#include <uapi/linux/mpls.h>
#define MPLS_HLEN 4
@@ -29,6 +29,7 @@
#include <linux/sock_diag.h>
#include <linux/in.h>
#include <linux/inet.h>
+#include <linux/mpls.h>
#include <linux/netdevice.h>
#include <linux/if_packet.h>
#include <linux/if_arp.h>
@@ -56,6 +57,7 @@
#include <net/sock_reuseport.h>
#include <net/busy_poll.h>
#include <net/tcp.h>
+#include <net/mpls.h>
#include <linux/bpf_trace.h>
/**
@@ -170,7 +170,7 @@ static u32 mpls_multipath_hash(struct mpls_route *rt, struct sk_buff *skb)
break;
/* Read and decode the current label */
- hdr = mpls_hdr(skb) + label_index;
+ hdr = skb_mpls_hdr(skb) + label_index;
dec = mpls_entry_decode(hdr);
/* RFC6790 - reserved labels MUST NOT be used as keys
@@ -379,7 +379,7 @@ static int mpls_forward(struct sk_buff *skb, struct net_device *dev,
goto err;
/* Read and decode the label */
- hdr = mpls_hdr(skb);
+ hdr = skb_mpls_hdr(skb);
dec = mpls_entry_decode(hdr);
rt = mpls_route_input_rcu(net, dec.label);
@@ -440,7 +440,7 @@ static int mpls_forward(struct sk_buff *skb, struct net_device *dev,
skb_push(skb, new_header_size);
skb_reset_network_header(skb);
/* Push the new labels */
- hdr = mpls_hdr(skb);
+ hdr = skb_mpls_hdr(skb);
bos = dec.bos;
for (i = nh->nh_labels - 1; i >= 0; i--) {
hdr[i] = mpls_entry_encode(nh->nh_label[i],
@@ -2203,7 +2203,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
skb_reset_network_header(skb);
/* Push new labels */
- hdr = mpls_hdr(skb);
+ hdr = skb_mpls_hdr(skb);
bos = true;
for (i = n_labels - 1; i >= 0; i--) {
hdr[i] = mpls_entry_encode(labels[i],
@@ -8,13 +8,6 @@
*/
#define MAX_NEW_LABELS 30
-struct mpls_entry_decoded {
- u32 label;
- u8 ttl;
- u8 tc;
- u8 bos;
-};
-
struct mpls_pcpu_stats {
struct mpls_link_stats stats;
struct u64_stats_sync syncp;
@@ -172,30 +165,6 @@ struct mpls_route { /* next hop label forwarding entry */
#define endfor_nexthops(rt) }
-static inline struct mpls_shim_hdr mpls_entry_encode(u32 label, unsigned ttl, unsigned tc, bool bos)
-{
- struct mpls_shim_hdr result;
- result.label_stack_entry =
- cpu_to_be32((label << MPLS_LS_LABEL_SHIFT) |
- (tc << MPLS_LS_TC_SHIFT) |
- (bos ? (1 << MPLS_LS_S_SHIFT) : 0) |
- (ttl << MPLS_LS_TTL_SHIFT));
- return result;
-}
-
-static inline struct mpls_entry_decoded mpls_entry_decode(struct mpls_shim_hdr *hdr)
-{
- struct mpls_entry_decoded result;
- unsigned entry = be32_to_cpu(hdr->label_stack_entry);
-
- result.label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT;
- result.ttl = (entry & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT;
- result.tc = (entry & MPLS_LS_TC_MASK) >> MPLS_LS_TC_SHIFT;
- result.bos = (entry & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT;
-
- return result;
-}
-
static inline struct mpls_dev *mpls_dev_get(const struct net_device *dev)
{
return rcu_dereference_rtnl(dev->mpls_ptr);
@@ -127,7 +127,7 @@ static int mpls_xmit(struct sk_buff *skb)
skb->protocol = htons(ETH_P_MPLS_UC);
/* Push the new labels */
- hdr = mpls_hdr(skb);
+ hdr = skb_mpls_hdr(skb);
bos = true;
for (i = tun_encap_info->labels - 1; i >= 0; i--) {
hdr[i] = mpls_entry_encode(tun_encap_info->label[i],
@@ -205,7 +205,7 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
skb_reset_mac_header(skb);
skb_set_network_header(skb, skb->mac_len);
- new_mpls_lse = mpls_hdr(skb);
+ new_mpls_lse = skb_mpls_hdr(skb);
new_mpls_lse->label_stack_entry = mpls->mpls_lse;
skb_postpush_rcsum(skb, new_mpls_lse, MPLS_HLEN);
@@ -227,7 +227,7 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key,
if (unlikely(err))
return err;
- skb_postpull_rcsum(skb, mpls_hdr(skb), MPLS_HLEN);
+ skb_postpull_rcsum(skb, skb_mpls_hdr(skb), MPLS_HLEN);
memmove(skb_mac_header(skb) + MPLS_HLEN, skb_mac_header(skb),
skb->mac_len);
@@ -239,10 +239,10 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key,
if (ovs_key_mac_proto(key) == MAC_PROTO_ETHERNET) {
struct ethhdr *hdr;
- /* mpls_hdr() is used to locate the ethertype field correctly in the
- * presence of VLAN tags.
+ /* skb_mpls_hdr() is used to locate the ethertype field
+ * correctly in the presence of VLAN tags.
*/
- hdr = (struct ethhdr *)((void *)mpls_hdr(skb) - ETH_HLEN);
+ hdr = (struct ethhdr *)((void *)skb_mpls_hdr(skb) - ETH_HLEN);
update_ethertype(skb, hdr, ethertype);
}
if (eth_p_mpls(skb->protocol))
@@ -263,7 +263,7 @@ static int set_mpls(struct sk_buff *skb, struct sw_flow_key *flow_key,
if (unlikely(err))
return err;
- stack = mpls_hdr(skb);
+ stack = skb_mpls_hdr(skb);
lse = OVS_MASKED(stack->label_stack_entry, *mpls_lse, *mask);
if (skb->ip_summed == CHECKSUM_COMPLETE) {
__be32 diff[] = { ~(stack->label_stack_entry), lse };