mirror of
https://github.com/openvswitch/ovs
synced 2025-10-25 15:07:05 +00:00
datapath: Fix few mpls issues.
Found during MPLS upstreaming. Also sync-up MPLS header files with upstream code. Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
This commit is contained in:
@@ -27,7 +27,6 @@ openvswitch_headers = \
|
|||||||
flow.h \
|
flow.h \
|
||||||
flow_netlink.h \
|
flow_netlink.h \
|
||||||
flow_table.h \
|
flow_table.h \
|
||||||
mpls.h \
|
|
||||||
vlan.h \
|
vlan.h \
|
||||||
vport.h \
|
vport.h \
|
||||||
vport-internal_dev.h \
|
vport-internal_dev.h \
|
||||||
|
|||||||
@@ -32,11 +32,11 @@
|
|||||||
#include <net/ipv6.h>
|
#include <net/ipv6.h>
|
||||||
#include <net/checksum.h>
|
#include <net/checksum.h>
|
||||||
#include <net/dsfield.h>
|
#include <net/dsfield.h>
|
||||||
|
#include <net/mpls.h>
|
||||||
#include <net/sctp/checksum.h>
|
#include <net/sctp/checksum.h>
|
||||||
|
|
||||||
#include "datapath.h"
|
#include "datapath.h"
|
||||||
#include "gso.h"
|
#include "gso.h"
|
||||||
#include "mpls.h"
|
|
||||||
#include "vlan.h"
|
#include "vlan.h"
|
||||||
#include "vport.h"
|
#include "vport.h"
|
||||||
|
|
||||||
@@ -133,25 +133,16 @@ static int make_writable(struct sk_buff *skb, int write_len)
|
|||||||
return pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
|
return pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The end of the mac header.
|
|
||||||
*
|
|
||||||
* For non-MPLS skbs this will correspond to the network header.
|
|
||||||
* For MPLS skbs it will be before the network_header as the MPLS
|
|
||||||
* label stack lies between the end of the mac header and the network
|
|
||||||
* header. That is, for MPLS skbs the end of the mac header
|
|
||||||
* is the top of the MPLS label stack.
|
|
||||||
*/
|
|
||||||
static unsigned char *mac_header_end(const struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
return skb_mac_header(skb) + skb->mac_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
|
static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
|
||||||
const struct ovs_action_push_mpls *mpls)
|
const struct ovs_action_push_mpls *mpls)
|
||||||
{
|
{
|
||||||
__be32 *new_mpls_lse;
|
__be32 *new_mpls_lse;
|
||||||
struct ethhdr *hdr;
|
struct ethhdr *hdr;
|
||||||
|
|
||||||
|
/* Networking stack do not allow simultaneous Tunnel and MPLS GSO. */
|
||||||
|
if (skb_encapsulation(skb))
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
if (skb_cow_head(skb, MPLS_HLEN) < 0)
|
if (skb_cow_head(skb, MPLS_HLEN) < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@@ -160,7 +151,7 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
|
|||||||
skb->mac_len);
|
skb->mac_len);
|
||||||
skb_reset_mac_header(skb);
|
skb_reset_mac_header(skb);
|
||||||
|
|
||||||
new_mpls_lse = (__be32 *)mac_header_end(skb);
|
new_mpls_lse = (__be32 *)skb_mpls_header(skb);
|
||||||
*new_mpls_lse = mpls->mpls_lse;
|
*new_mpls_lse = mpls->mpls_lse;
|
||||||
|
|
||||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||||
@@ -172,6 +163,7 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
|
|||||||
if (!ovs_skb_get_inner_protocol(skb))
|
if (!ovs_skb_get_inner_protocol(skb))
|
||||||
ovs_skb_set_inner_protocol(skb, skb->protocol);
|
ovs_skb_set_inner_protocol(skb, skb->protocol);
|
||||||
skb->protocol = mpls->mpls_ethertype;
|
skb->protocol = mpls->mpls_ethertype;
|
||||||
|
|
||||||
invalidate_flow_key(key);
|
invalidate_flow_key(key);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -188,7 +180,7 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key,
|
|||||||
|
|
||||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||||
skb->csum = csum_sub(skb->csum,
|
skb->csum = csum_sub(skb->csum,
|
||||||
csum_partial(mac_header_end(skb),
|
csum_partial(skb_mpls_header(skb),
|
||||||
MPLS_HLEN, 0));
|
MPLS_HLEN, 0));
|
||||||
|
|
||||||
memmove(skb_mac_header(skb) + MPLS_HLEN, skb_mac_header(skb),
|
memmove(skb_mac_header(skb) + MPLS_HLEN, skb_mac_header(skb),
|
||||||
@@ -197,13 +189,14 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key,
|
|||||||
__skb_pull(skb, MPLS_HLEN);
|
__skb_pull(skb, MPLS_HLEN);
|
||||||
skb_reset_mac_header(skb);
|
skb_reset_mac_header(skb);
|
||||||
|
|
||||||
/* mac_header_end() is used to locate the ethertype
|
/* skb_mpls_header() is used to locate the ethertype
|
||||||
* field correctly in the presence of VLAN tags.
|
* field correctly in the presence of VLAN tags.
|
||||||
*/
|
*/
|
||||||
hdr = (struct ethhdr *)(mac_header_end(skb) - ETH_HLEN);
|
hdr = (struct ethhdr *)(skb_mpls_header(skb) - ETH_HLEN);
|
||||||
hdr->h_proto = ethertype;
|
hdr->h_proto = ethertype;
|
||||||
if (eth_p_mpls(skb->protocol))
|
if (eth_p_mpls(skb->protocol))
|
||||||
skb->protocol = ethertype;
|
skb->protocol = ethertype;
|
||||||
|
|
||||||
invalidate_flow_key(key);
|
invalidate_flow_key(key);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -211,13 +204,14 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key,
|
|||||||
static int set_mpls(struct sk_buff *skb, struct sw_flow_key *key,
|
static int set_mpls(struct sk_buff *skb, struct sw_flow_key *key,
|
||||||
const __be32 *mpls_lse)
|
const __be32 *mpls_lse)
|
||||||
{
|
{
|
||||||
__be32 *stack = (__be32 *)mac_header_end(skb);
|
__be32 *stack;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = make_writable(skb, skb->mac_len + MPLS_HLEN);
|
err = make_writable(skb, skb->mac_len + MPLS_HLEN);
|
||||||
if (unlikely(err))
|
if (unlikely(err))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
stack = (__be32 *)skb_mpls_header(skb);
|
||||||
if (skb->ip_summed == CHECKSUM_COMPLETE) {
|
if (skb->ip_summed == CHECKSUM_COMPLETE) {
|
||||||
__be32 diff[] = { ~(*stack), *mpls_lse };
|
__be32 diff[] = { ~(*stack), *mpls_lse };
|
||||||
skb->csum = ~csum_partial((char *)diff, sizeof(diff),
|
skb->csum = ~csum_partial((char *)diff, sizeof(diff),
|
||||||
@@ -300,7 +294,6 @@ static int push_vlan(struct sk_buff *skb, struct sw_flow_key *key,
|
|||||||
|
|
||||||
if (!__vlan_put_tag(skb, skb->vlan_proto, current_tag))
|
if (!__vlan_put_tag(skb, skb->vlan_proto, current_tag))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Update mac_len for subsequent MPLS actions */
|
/* Update mac_len for subsequent MPLS actions */
|
||||||
skb->mac_len += VLAN_HLEN;
|
skb->mac_len += VLAN_HLEN;
|
||||||
|
|
||||||
@@ -629,10 +622,10 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
|
|||||||
static int output_userspace(struct datapath *dp, struct sk_buff *skb,
|
static int output_userspace(struct datapath *dp, struct sk_buff *skb,
|
||||||
struct sw_flow_key *key, const struct nlattr *attr)
|
struct sw_flow_key *key, const struct nlattr *attr)
|
||||||
{
|
{
|
||||||
|
struct ovs_tunnel_info info;
|
||||||
struct dp_upcall_info upcall;
|
struct dp_upcall_info upcall;
|
||||||
const struct nlattr *a;
|
const struct nlattr *a;
|
||||||
int rem;
|
int rem;
|
||||||
struct ovs_tunnel_info info;
|
|
||||||
|
|
||||||
upcall.cmd = OVS_PACKET_CMD_ACTION;
|
upcall.cmd = OVS_PACKET_CMD_ACTION;
|
||||||
upcall.userdata = NULL;
|
upcall.userdata = NULL;
|
||||||
|
|||||||
@@ -76,4 +76,14 @@ static inline struct rtable *find_route(struct net *net,
|
|||||||
return rt;
|
return rt;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
|
||||||
|
static inline bool skb_encapsulation(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return skb->encapsulation;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define skb_encapsulation(skb) false
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* compat.h */
|
#endif /* compat.h */
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <linux/if_arp.h>
|
#include <linux/if_arp.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/ipv6.h>
|
#include <linux/ipv6.h>
|
||||||
|
#include <linux/mpls.h>
|
||||||
#include <linux/sctp.h>
|
#include <linux/sctp.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/tcp.h>
|
#include <linux/tcp.h>
|
||||||
@@ -41,13 +42,13 @@
|
|||||||
#include <linux/rculist.h>
|
#include <linux/rculist.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
#include <net/ipv6.h>
|
#include <net/ipv6.h>
|
||||||
|
#include <net/mpls.h>
|
||||||
#include <net/ndisc.h>
|
#include <net/ndisc.h>
|
||||||
|
|
||||||
#include "datapath.h"
|
#include "datapath.h"
|
||||||
#include "flow.h"
|
#include "flow.h"
|
||||||
#include "flow_netlink.h"
|
#include "flow_netlink.h"
|
||||||
|
|
||||||
#include "mpls.h"
|
|
||||||
#include "vlan.h"
|
#include "vlan.h"
|
||||||
|
|
||||||
u64 ovs_flow_used_time(unsigned long flow_jiffies)
|
u64 ovs_flow_used_time(unsigned long flow_jiffies)
|
||||||
@@ -609,7 +610,7 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
|
|||||||
memcpy(&key->mpls.top_lse, &lse, MPLS_HLEN);
|
memcpy(&key->mpls.top_lse, &lse, MPLS_HLEN);
|
||||||
|
|
||||||
skb_set_network_header(skb, skb->mac_len + stack_len);
|
skb_set_network_header(skb, skb->mac_len + stack_len);
|
||||||
if (lse & htonl(MPLS_BOS_MASK))
|
if (lse & htonl(MPLS_LS_S_MASK))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
stack_len += MPLS_HLEN;
|
stack_len += MPLS_HLEN;
|
||||||
|
|||||||
@@ -18,9 +18,6 @@
|
|||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#include "flow.h"
|
|
||||||
#include "datapath.h"
|
|
||||||
#include "mpls.h"
|
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
@@ -45,10 +42,12 @@
|
|||||||
#include <linux/rculist.h>
|
#include <linux/rculist.h>
|
||||||
#include <net/geneve.h>
|
#include <net/geneve.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
#include <net/ip_tunnels.h>
|
|
||||||
#include <net/ipv6.h>
|
#include <net/ipv6.h>
|
||||||
#include <net/ndisc.h>
|
#include <net/ndisc.h>
|
||||||
|
#include <net/mpls.h>
|
||||||
|
|
||||||
|
#include "datapath.h"
|
||||||
|
#include "flow.h"
|
||||||
#include "flow_netlink.h"
|
#include "flow_netlink.h"
|
||||||
|
|
||||||
static void update_range(struct sw_flow_match *match,
|
static void update_range(struct sw_flow_match *match,
|
||||||
@@ -1665,6 +1664,9 @@ static int validate_set(const struct nlattr *a,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OVS_KEY_ATTR_TUNNEL:
|
case OVS_KEY_ATTR_TUNNEL:
|
||||||
|
if (eth_p_mpls(eth_type))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
*set_tun = true;
|
*set_tun = true;
|
||||||
err = validate_and_copy_set_tun(a, sfa, log);
|
err = validate_and_copy_set_tun(a, sfa, log);
|
||||||
if (err)
|
if (err)
|
||||||
@@ -1778,6 +1780,7 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
|
|||||||
__be16 eth_type, __be16 vlan_tci, bool log)
|
__be16 eth_type, __be16 vlan_tci, bool log)
|
||||||
{
|
{
|
||||||
const struct nlattr *a;
|
const struct nlattr *a;
|
||||||
|
bool out_tnl_port = false;
|
||||||
int rem, err;
|
int rem, err;
|
||||||
|
|
||||||
if (depth >= SAMPLE_ACTION_DEPTH)
|
if (depth >= SAMPLE_ACTION_DEPTH)
|
||||||
@@ -1820,6 +1823,7 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
|
|||||||
case OVS_ACTION_ATTR_OUTPUT:
|
case OVS_ACTION_ATTR_OUTPUT:
|
||||||
if (nla_get_u32(a) >= DP_MAX_PORTS)
|
if (nla_get_u32(a) >= DP_MAX_PORTS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
out_tnl_port = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OVS_ACTION_ATTR_HASH: {
|
case OVS_ACTION_ATTR_HASH: {
|
||||||
@@ -1854,6 +1858,12 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
|
|||||||
case OVS_ACTION_ATTR_PUSH_MPLS: {
|
case OVS_ACTION_ATTR_PUSH_MPLS: {
|
||||||
const struct ovs_action_push_mpls *mpls = nla_data(a);
|
const struct ovs_action_push_mpls *mpls = nla_data(a);
|
||||||
|
|
||||||
|
/* Networking stack do not allow simultaneous Tunnel
|
||||||
|
* and MPLS GSO.
|
||||||
|
*/
|
||||||
|
if (out_tnl_port)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (!eth_p_mpls(mpls->mpls_ethertype))
|
if (!eth_p_mpls(mpls->mpls_ethertype))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
/* Prohibit push MPLS other than to a white list
|
/* Prohibit push MPLS other than to a white list
|
||||||
@@ -1888,10 +1898,11 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OVS_ACTION_ATTR_SET:
|
case OVS_ACTION_ATTR_SET:
|
||||||
err = validate_set(a, key, sfa, &skip_copy, eth_type,
|
err = validate_set(a, key, sfa,
|
||||||
log);
|
&out_tnl_port, eth_type, log);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
skip_copy = out_tnl_port;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OVS_ACTION_ATTR_SAMPLE:
|
case OVS_ACTION_ATTR_SAMPLE:
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ openvswitch_headers += \
|
|||||||
linux/compat/include/linux/kernel.h \
|
linux/compat/include/linux/kernel.h \
|
||||||
linux/compat/include/linux/list.h \
|
linux/compat/include/linux/list.h \
|
||||||
linux/compat/include/linux/log2.h \
|
linux/compat/include/linux/log2.h \
|
||||||
|
linux/compat/include/linux/mpls.h \
|
||||||
linux/compat/include/linux/net.h \
|
linux/compat/include/linux/net.h \
|
||||||
linux/compat/include/linux/random.h \
|
linux/compat/include/linux/random.h \
|
||||||
linux/compat/include/linux/netdevice.h \
|
linux/compat/include/linux/netdevice.h \
|
||||||
@@ -70,6 +71,7 @@ openvswitch_headers += \
|
|||||||
linux/compat/include/net/ip.h \
|
linux/compat/include/net/ip.h \
|
||||||
linux/compat/include/net/ip_tunnels.h \
|
linux/compat/include/net/ip_tunnels.h \
|
||||||
linux/compat/include/net/ipv6.h \
|
linux/compat/include/net/ipv6.h \
|
||||||
|
linux/compat/include/net/mpls.h \
|
||||||
linux/compat/include/net/net_namespace.h \
|
linux/compat/include/net/net_namespace.h \
|
||||||
linux/compat/include/net/netlink.h \
|
linux/compat/include/net/netlink.h \
|
||||||
linux/compat/include/net/udp.h \
|
linux/compat/include/net/udp.h \
|
||||||
|
|||||||
@@ -34,12 +34,12 @@
|
|||||||
|
|
||||||
#include <net/gre.h>
|
#include <net/gre.h>
|
||||||
#include <net/icmp.h>
|
#include <net/icmp.h>
|
||||||
|
#include <net/mpls.h>
|
||||||
#include <net/protocol.h>
|
#include <net/protocol.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
#include <net/xfrm.h>
|
#include <net/xfrm.h>
|
||||||
|
|
||||||
#include "gso.h"
|
#include "gso.h"
|
||||||
#include "mpls.h"
|
|
||||||
#include "vlan.h"
|
#include "vlan.h"
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) && \
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) && \
|
||||||
|
|||||||
@@ -102,11 +102,19 @@ static inline void ovs_skb_init_inner_protocol(struct sk_buff *skb) {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
|
||||||
static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
|
static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
|
||||||
__be16 ethertype)
|
__be16 ethertype)
|
||||||
{
|
{
|
||||||
skb->inner_protocol = ethertype;
|
skb->inner_protocol = ethertype;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb,
|
||||||
|
__be16 ethertype)
|
||||||
|
{
|
||||||
|
skb_set_inner_protocol(skb, ethertype);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline __be16 ovs_skb_get_inner_protocol(struct sk_buff *skb)
|
static inline __be16 ovs_skb_get_inner_protocol(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
|||||||
40
datapath/linux/compat/include/linux/mpls.h
Normal file
40
datapath/linux/compat/include/linux/mpls.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef _UAPI_MPLS_WRAPPER_H
|
||||||
|
#define _UAPI_MPLS_WRAPPER_H
|
||||||
|
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
|
||||||
|
#include_next <linux/mpls.h>
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
/* Reference: RFC 5462, RFC 3032
|
||||||
|
*
|
||||||
|
* 0 1 2 3
|
||||||
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Label | TC |S| TTL |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
*
|
||||||
|
* Label: Label Value, 20 bits
|
||||||
|
* TC: Traffic Class field, 3 bits
|
||||||
|
* S: Bottom of Stack, 1 bit
|
||||||
|
* TTL: Time to Live, 8 bits
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct mpls_label {
|
||||||
|
__be32 entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MPLS_LS_LABEL_MASK 0xFFFFF000
|
||||||
|
#define MPLS_LS_LABEL_SHIFT 12
|
||||||
|
#define MPLS_LS_TC_MASK 0x00000E00
|
||||||
|
#define MPLS_LS_TC_SHIFT 9
|
||||||
|
#define MPLS_LS_S_MASK 0x00000100
|
||||||
|
#define MPLS_LS_S_SHIFT 8
|
||||||
|
#define MPLS_LS_TTL_MASK 0x000000FF
|
||||||
|
#define MPLS_LS_TTL_SHIFT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _UAPI_MPLS_WRAPPER_H */
|
||||||
39
datapath/linux/compat/include/net/mpls.h
Normal file
39
datapath/linux/compat/include/net/mpls.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 Nicira, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of version 2 of the GNU General Public
|
||||||
|
* License as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NET_MPLS_WRAPPER_H
|
||||||
|
#define _NET_MPLS_WRAPPER_H 1
|
||||||
|
|
||||||
|
#include <linux/if_ether.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
|
#define MPLS_HLEN 4
|
||||||
|
|
||||||
|
static inline bool eth_p_mpls(__be16 eth_type)
|
||||||
|
{
|
||||||
|
return eth_type == htons(ETH_P_MPLS_UC) ||
|
||||||
|
eth_type == htons(ETH_P_MPLS_MC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For non-MPLS skbs this will correspond to the network header.
|
||||||
|
* For MPLS skbs it will be before the network_header as the MPLS
|
||||||
|
* label stack lies between the end of the mac header and the network
|
||||||
|
* header. That is, for MPLS skbs the end of the mac header
|
||||||
|
* is the top of the MPLS label stack.
|
||||||
|
*/
|
||||||
|
static inline unsigned char *skb_mpls_header(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return skb_mac_header(skb) + skb->mac_len;
|
||||||
|
}
|
||||||
|
#endif /* _NET_MPLS_WRAPPER_H */
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/if_vlan.h>
|
#include <linux/if_vlan.h>
|
||||||
|
#include <net/mpls.h>
|
||||||
|
|
||||||
#include "mpls.h"
|
|
||||||
#include "gso.h"
|
#include "gso.h"
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
#ifndef MPLS_H
|
|
||||||
#define MPLS_H 1
|
|
||||||
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
|
|
||||||
#define MPLS_BOS_MASK 0x00000100
|
|
||||||
#define MPLS_HLEN 4
|
|
||||||
|
|
||||||
static inline bool eth_p_mpls(__be16 eth_type)
|
|
||||||
{
|
|
||||||
return eth_type == htons(ETH_P_MPLS_UC) ||
|
|
||||||
eth_type == htons(ETH_P_MPLS_MC);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Reference in New Issue
Block a user