* [PATCH net-next v6 3/3] openvswitch: enable NSH support
From: Yi Yang @ 2017-08-25 14:20 UTC (permalink / raw)
To: netdev; +Cc: dev, jbenc, e, blp, jan.scheurich, Yi Yang
In-Reply-To: <1503670805-31051-1-git-send-email-yi.y.yang@intel.com>
OVS master and 2.8 branch has merged NSH userspace
patch series, this patch is to enable NSH support
in kernel data path in order that OVS can support
NSH in compat mode by porting this.
Signed-off-by: Yi Yang <yi.y.yang@intel.com>
---
drivers/net/vxlan.c | 7 +
include/uapi/linux/openvswitch.h | 28 +++
net/openvswitch/actions.c | 178 +++++++++++++++++
net/openvswitch/flow.c | 55 ++++++
net/openvswitch/flow.h | 11 ++
net/openvswitch/flow_netlink.c | 404 ++++++++++++++++++++++++++++++++++++++-
net/openvswitch/flow_netlink.h | 4 +
7 files changed, 686 insertions(+), 1 deletion(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index ae3a1da..a36c41e 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -27,6 +27,7 @@
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <net/vxlan.h>
+#include <net/nsh.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ip6_tunnel.h>
@@ -1268,6 +1269,9 @@ static bool vxlan_parse_gpe_hdr(struct vxlanhdr *unparsed,
case VXLAN_GPE_NP_IPV6:
*protocol = htons(ETH_P_IPV6);
break;
+ case VXLAN_GPE_NP_NSH:
+ *protocol = htons(ETH_P_NSH);
+ break;
case VXLAN_GPE_NP_ETHERNET:
*protocol = htons(ETH_P_TEB);
break;
@@ -1807,6 +1811,9 @@ static int vxlan_build_gpe_hdr(struct vxlanhdr *vxh, u32 vxflags,
case htons(ETH_P_IPV6):
gpe->next_protocol = VXLAN_GPE_NP_IPV6;
return 0;
+ case htons(ETH_P_NSH):
+ gpe->next_protocol = VXLAN_GPE_NP_NSH;
+ return 0;
case htons(ETH_P_TEB):
gpe->next_protocol = VXLAN_GPE_NP_ETHERNET;
return 0;
diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index 156ee4c..91dee5b 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -333,6 +333,7 @@ enum ovs_key_attr {
OVS_KEY_ATTR_CT_LABELS, /* 16-octet connection tracking label */
OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4, /* struct ovs_key_ct_tuple_ipv4 */
OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6, /* struct ovs_key_ct_tuple_ipv6 */
+ OVS_KEY_ATTR_NSH, /* Nested set of ovs_nsh_key_* */
#ifdef __KERNEL__
OVS_KEY_ATTR_TUNNEL_INFO, /* struct ip_tunnel_info */
@@ -491,6 +492,29 @@ struct ovs_key_ct_tuple_ipv6 {
__u8 ipv6_proto;
};
+enum ovs_nsh_key_attr {
+ OVS_NSH_KEY_ATTR_BASE, /* struct ovs_nsh_key_base. */
+ OVS_NSH_KEY_ATTR_MD1, /* struct ovs_nsh_key_md1. */
+ OVS_NSH_KEY_ATTR_MD2, /* variable-length octets for MD type 2. */
+ __OVS_NSH_KEY_ATTR_MAX
+};
+
+#define OVS_NSH_KEY_ATTR_MAX (__OVS_NSH_KEY_ATTR_MAX - 1)
+
+struct ovs_nsh_key_base {
+ __u8 flags;
+ __u8 ttl;
+ __u8 mdtype;
+ __u8 np;
+ __be32 path_hdr;
+};
+
+#define NSH_MD1_CONTEXT_SIZE 4
+
+struct ovs_nsh_key_md1 {
+ __be32 context[NSH_MD1_CONTEXT_SIZE];
+};
+
/**
* enum ovs_flow_attr - attributes for %OVS_FLOW_* commands.
* @OVS_FLOW_ATTR_KEY: Nested %OVS_KEY_ATTR_* attributes specifying the flow
@@ -806,6 +830,8 @@ struct ovs_action_push_eth {
* packet.
* @OVS_ACTION_ATTR_POP_ETH: Pop the outermost Ethernet header off the
* packet.
+ * @OVS_ACTION_ATTR_PUSH_NSH: push NSH header to the packet.
+ * @OVS_ACTION_ATTR_POP_NSH: pop the outermost NSH header off the packet.
*
* Only a single header can be set with a single %OVS_ACTION_ATTR_SET. Not all
* fields within a header are modifiable, e.g. the IPv4 protocol and fragment
@@ -835,6 +861,8 @@ enum ovs_action_attr {
OVS_ACTION_ATTR_TRUNC, /* u32 struct ovs_action_trunc. */
OVS_ACTION_ATTR_PUSH_ETH, /* struct ovs_action_push_eth. */
OVS_ACTION_ATTR_POP_ETH, /* No argument. */
+ OVS_ACTION_ATTR_PUSH_NSH, /* Nested OVS_NSH_KEY_ATTR_*. */
+ OVS_ACTION_ATTR_POP_NSH, /* No argument. */
__OVS_ACTION_ATTR_MAX, /* Nothing past this will be accepted
* from userspace. */
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index a54a556..9ca1a84 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -43,6 +43,7 @@
#include "flow.h"
#include "conntrack.h"
#include "vport.h"
+#include "flow_netlink.h"
struct deferred_action {
struct sk_buff *skb;
@@ -380,6 +381,95 @@ static int push_eth(struct sk_buff *skb, struct sw_flow_key *key,
return 0;
}
+static int push_nsh(struct sk_buff *skb, struct sw_flow_key *key,
+ const struct nsh_hdr *nsh_src)
+{
+ struct nsh_hdr *nsh;
+ size_t length = nsh_hdr_len(nsh_src);
+ u8 next_proto;
+
+ if (key->mac_proto == MAC_PROTO_ETHERNET) {
+ next_proto = NSH_P_ETHERNET;
+ } else {
+ switch (ntohs(skb->protocol)) {
+ case ETH_P_IP:
+ next_proto = NSH_P_IPV4;
+ break;
+ case ETH_P_IPV6:
+ next_proto = NSH_P_IPV6;
+ break;
+ case ETH_P_NSH:
+ next_proto = NSH_P_NSH;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+ }
+
+ /* Add the NSH header */
+ if (skb_cow_head(skb, length) < 0)
+ return -ENOMEM;
+
+ skb_push(skb, length);
+ nsh = (struct nsh_hdr *)(skb->data);
+ memcpy(nsh, nsh_src, length);
+ nsh->np = next_proto;
+ nsh->mdtype &= NSH_MDTYPE_MASK;
+
+ skb->protocol = htons(ETH_P_NSH);
+ key->eth.type = htons(ETH_P_NSH);
+ skb_reset_mac_header(skb);
+ skb_reset_mac_len(skb);
+
+ /* safe right before invalidate_flow_key */
+ key->mac_proto = MAC_PROTO_NONE;
+ invalidate_flow_key(key);
+ return 0;
+}
+
+static int pop_nsh(struct sk_buff *skb, struct sw_flow_key *key)
+{
+ struct nsh_hdr *nsh = (struct nsh_hdr *)(skb->data);
+ size_t length;
+ u16 inner_proto;
+
+ if (ovs_key_mac_proto(key) != MAC_PROTO_NONE ||
+ skb->protocol != htons(ETH_P_NSH)) {
+ return -EINVAL;
+ }
+
+ switch (nsh->np) {
+ case NSH_P_ETHERNET:
+ inner_proto = htons(ETH_P_TEB);
+ break;
+ case NSH_P_IPV4:
+ inner_proto = htons(ETH_P_IP);
+ break;
+ case NSH_P_IPV6:
+ inner_proto = htons(ETH_P_IPV6);
+ break;
+ case NSH_P_NSH:
+ inner_proto = htons(ETH_P_NSH);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ length = nsh_hdr_len(nsh);
+ skb_pull(skb, length);
+ skb_reset_mac_header(skb);
+ skb_reset_mac_len(skb);
+ skb->protocol = inner_proto;
+
+ /* safe right before invalidate_flow_key */
+ if (inner_proto == htons(ETH_P_TEB))
+ key->mac_proto = MAC_PROTO_ETHERNET;
+ else
+ key->mac_proto = MAC_PROTO_NONE;
+ invalidate_flow_key(key);
+ return 0;
+}
+
static void update_ip_l4_checksum(struct sk_buff *skb, struct iphdr *nh,
__be32 addr, __be32 new_addr)
{
@@ -602,6 +692,53 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key,
return 0;
}
+static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key,
+ const struct ovs_key_nsh *key,
+ const struct ovs_key_nsh *mask)
+{
+ struct nsh_hdr *nsh;
+ int err;
+ u8 flags;
+ u8 ttl;
+ int i;
+
+ err = skb_ensure_writable(skb, skb_network_offset(skb) +
+ sizeof(struct nsh_hdr));
+ if (unlikely(err))
+ return err;
+
+ nsh = (struct nsh_hdr *)skb_network_header(skb);
+
+ flags = nsh_get_flags(nsh);
+ flags = OVS_MASKED(flags, key->flags, mask->flags);
+ flow_key->nsh.flags = flags;
+ ttl = nsh_get_ttl(nsh);
+ ttl = OVS_MASKED(ttl, key->ttl, mask->ttl);
+ flow_key->nsh.ttl = ttl;
+ nsh_set_flags_and_ttl(nsh, flags, ttl);
+ nsh->path_hdr = OVS_MASKED(nsh->path_hdr, key->path_hdr,
+ mask->path_hdr);
+ flow_key->nsh.path_hdr = nsh->path_hdr;
+ switch (nsh->mdtype) {
+ case NSH_M_TYPE1:
+ for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++) {
+ nsh->md1.context[i] =
+ OVS_MASKED(nsh->md1.context[i], key->context[i],
+ mask->context[i]);
+ }
+ memcpy(flow_key->nsh.context, nsh->md1.context,
+ sizeof(nsh->md1.context));
+ break;
+ case NSH_M_TYPE2:
+ memset(flow_key->nsh.context, 0,
+ sizeof(flow_key->nsh.context));
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
/* Must follow skb_ensure_writable() since that can move the skb data. */
static void set_tp_port(struct sk_buff *skb, __be16 *port,
__be16 new_port, __sum16 *check)
@@ -1024,6 +1161,32 @@ static int execute_masked_set_action(struct sk_buff *skb,
get_mask(a, struct ovs_key_ethernet *));
break;
+ case OVS_KEY_ATTR_NSH: {
+ struct ovs_key_nsh nsh;
+ struct ovs_key_nsh nsh_mask;
+ size_t size = nla_len(a) / 2;
+ struct {
+ struct nlattr nla;
+ u8 data[size];
+ } attr, mask;
+
+ attr.nla.nla_type = nla_type(a);
+ attr.nla.nla_len = NLA_HDRLEN + size;
+ memcpy(attr.data, (char *)(a + 1), size);
+
+ mask.nla = attr.nla;
+ memcpy(mask.data, (char *)(a + 1) + size, size);
+
+ err = nsh_key_from_nlattr(&attr.nla, &nsh);
+ if (err)
+ break;
+ err = nsh_key_from_nlattr(&mask.nla, &nsh_mask);
+ if (err)
+ break;
+ err = set_nsh(skb, flow_key, &nsh, &nsh_mask);
+ break;
+ }
+
case OVS_KEY_ATTR_IPV4:
err = set_ipv4(skb, flow_key, nla_data(a),
get_mask(a, struct ovs_key_ipv4 *));
@@ -1210,6 +1373,21 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
case OVS_ACTION_ATTR_POP_ETH:
err = pop_eth(skb, key);
break;
+
+ case OVS_ACTION_ATTR_PUSH_NSH: {
+ u8 buffer[NSH_HDR_MAX_LEN];
+ struct nsh_hdr *nsh_hdr = (struct nsh_hdr *)buffer;
+ const struct nsh_hdr *nsh_src = nsh_hdr;
+
+ nsh_hdr_from_nlattr(nla_data(a), nsh_hdr,
+ NSH_HDR_MAX_LEN);
+ err = push_nsh(skb, key, nsh_src);
+ break;
+ }
+
+ case OVS_ACTION_ATTR_POP_NSH:
+ err = pop_nsh(skb, key);
+ break;
}
if (unlikely(err)) {
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 8c94cef..34865b5 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -46,6 +46,7 @@
#include <net/ipv6.h>
#include <net/mpls.h>
#include <net/ndisc.h>
+#include <net/nsh.h>
#include "conntrack.h"
#include "datapath.h"
@@ -490,6 +491,56 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
return 0;
}
+static int parse_nsh(struct sk_buff *skb, struct sw_flow_key *key)
+{
+ struct nsh_hdr *nsh;
+ unsigned int nh_ofs = skb_network_offset(skb);
+ u8 version, length;
+ int err;
+
+ err = check_header(skb, nh_ofs + NSH_BASE_HDR_LEN);
+ if (unlikely(err))
+ return err;
+
+ nsh = (struct nsh_hdr *)skb_network_header(skb);
+ version = nsh_get_ver(nsh);
+ length = nsh_hdr_len(nsh);
+
+ if (version != 0)
+ return -EINVAL;
+
+ err = check_header(skb, nh_ofs + length);
+ if (unlikely(err))
+ return err;
+
+ nsh = (struct nsh_hdr *)skb_network_header(skb);
+ key->nsh.flags = nsh_get_flags(nsh);
+ key->nsh.ttl = nsh_get_ttl(nsh);
+ key->nsh.mdtype = nsh->mdtype;
+ key->nsh.np = nsh->np;
+ key->nsh.path_hdr = nsh->path_hdr;
+ switch (key->nsh.mdtype) {
+ case NSH_M_TYPE1:
+ if (length != NSH_M_TYPE1_LEN)
+ return -EINVAL;
+ memcpy(key->nsh.context, nsh->md1.context,
+ sizeof(nsh->md1));
+ break;
+ case NSH_M_TYPE2:
+ /* Don't support MD type 2 metedata parsing yet */
+ if (length < NSH_BASE_HDR_LEN)
+ return -EINVAL;
+
+ memset(key->nsh.context, 0,
+ sizeof(nsh->md1));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/**
* key_extract - extracts a flow key from an Ethernet frame.
* @skb: sk_buff that contains the frame, with skb->data pointing to the
@@ -735,6 +786,10 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
memset(&key->tp, 0, sizeof(key->tp));
}
}
+ } else if (key->eth.type == htons(ETH_P_NSH)) {
+ error = parse_nsh(skb, key);
+ if (error)
+ return error;
}
return 0;
}
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 1875bba..6a3cd9c 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -35,6 +35,7 @@
#include <net/inet_ecn.h>
#include <net/ip_tunnels.h>
#include <net/dst_metadata.h>
+#include <net/nsh.h>
struct sk_buff;
@@ -66,6 +67,15 @@ struct vlan_head {
(offsetof(struct sw_flow_key, recirc_id) + \
FIELD_SIZEOF(struct sw_flow_key, recirc_id))
+struct ovs_key_nsh {
+ u8 flags;
+ u8 ttl;
+ u8 mdtype;
+ u8 np;
+ __be32 path_hdr;
+ __be32 context[NSH_MD1_CONTEXT_SIZE];
+};
+
struct sw_flow_key {
u8 tun_opts[IP_TUNNEL_OPTS_MAX];
u8 tun_opts_len;
@@ -144,6 +154,7 @@ struct sw_flow_key {
};
} ipv6;
};
+ struct ovs_key_nsh nsh; /* network service header */
struct {
/* Connection tracking fields not packed above. */
struct {
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index e8eb427..3b7f166 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -78,9 +78,11 @@ static bool actions_may_change_flow(const struct nlattr *actions)
case OVS_ACTION_ATTR_HASH:
case OVS_ACTION_ATTR_POP_ETH:
case OVS_ACTION_ATTR_POP_MPLS:
+ case OVS_ACTION_ATTR_POP_NSH:
case OVS_ACTION_ATTR_POP_VLAN:
case OVS_ACTION_ATTR_PUSH_ETH:
case OVS_ACTION_ATTR_PUSH_MPLS:
+ case OVS_ACTION_ATTR_PUSH_NSH:
case OVS_ACTION_ATTR_PUSH_VLAN:
case OVS_ACTION_ATTR_SAMPLE:
case OVS_ACTION_ATTR_SET:
@@ -322,12 +324,27 @@ size_t ovs_tun_key_attr_size(void)
+ nla_total_size(2); /* OVS_TUNNEL_KEY_ATTR_TP_DST */
}
+size_t ovs_nsh_key_attr_size(void)
+{
+ /* Whenever adding new OVS_NSH_KEY_ FIELDS, we should consider
+ * updating this function.
+ */
+ return nla_total_size(NSH_BASE_HDR_LEN) /* OVS_NSH_KEY_ATTR_BASE */
+ /* OVS_NSH_KEY_ATTR_MD1 and OVS_NSH_KEY_ATTR_MD2 are
+ * mutually exclusive, so the bigger one can cover
+ * the small one.
+ *
+ * OVS_NSH_KEY_ATTR_MD2
+ */
+ + nla_total_size(NSH_CTX_HDRS_MAX_LEN);
+}
+
size_t ovs_key_attr_size(void)
{
/* Whenever adding new OVS_KEY_ FIELDS, we should consider
* updating this function.
*/
- BUILD_BUG_ON(OVS_KEY_ATTR_TUNNEL_INFO != 28);
+ BUILD_BUG_ON(OVS_KEY_ATTR_TUNNEL_INFO != 29);
return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */
+ nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */
@@ -341,6 +358,8 @@ size_t ovs_key_attr_size(void)
+ nla_total_size(4) /* OVS_KEY_ATTR_CT_MARK */
+ nla_total_size(16) /* OVS_KEY_ATTR_CT_LABELS */
+ nla_total_size(40) /* OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6 */
+ + nla_total_size(0) /* OVS_KEY_ATTR_NSH */
+ + ovs_nsh_key_attr_size()
+ nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */
+ nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
+ nla_total_size(4) /* OVS_KEY_ATTR_VLAN */
@@ -373,6 +392,13 @@ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1]
[OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = sizeof(struct in6_addr) },
};
+static const struct ovs_len_tbl
+ovs_nsh_key_attr_lens[OVS_NSH_KEY_ATTR_MAX + 1] = {
+ [OVS_NSH_KEY_ATTR_BASE] = { .len = 8 },
+ [OVS_NSH_KEY_ATTR_MD1] = { .len = 16 },
+ [OVS_NSH_KEY_ATTR_MD2] = { .len = OVS_ATTR_VARIABLE },
+};
+
/* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */
static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
[OVS_KEY_ATTR_ENCAP] = { .len = OVS_ATTR_NESTED },
@@ -405,6 +431,8 @@ static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
.len = sizeof(struct ovs_key_ct_tuple_ipv4) },
[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6] = {
.len = sizeof(struct ovs_key_ct_tuple_ipv6) },
+ [OVS_KEY_ATTR_NSH] = { .len = OVS_ATTR_NESTED,
+ .next = ovs_nsh_key_attr_lens, },
};
static bool check_attr_len(unsigned int attr_len, unsigned int expected_len)
@@ -1179,6 +1207,303 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
return 0;
}
+int nsh_hdr_from_nlattr(const struct nlattr *attr,
+ struct nsh_hdr *nsh, size_t size)
+{
+ struct nlattr *a;
+ int rem;
+ u8 flags = 0;
+ u8 ttl = 0;
+ int mdlen = 0;
+ bool has_md1 = false;
+ bool has_md2 = false;
+ u8 len;
+
+ nla_for_each_nested(a, attr, rem) {
+ int type = nla_type(a);
+
+ if (type > OVS_NSH_KEY_ATTR_MAX) {
+ OVS_NLERR(1, "nsh attr %d is out of range max %d",
+ type, OVS_NSH_KEY_ATTR_MAX);
+ return -EINVAL;
+ }
+
+ if (!check_attr_len(nla_len(a),
+ ovs_nsh_key_attr_lens[type].len)) {
+ OVS_NLERR(
+ 1,
+ "nsh attr %d has unexpected len %d expected %d",
+ type,
+ nla_len(a),
+ ovs_nsh_key_attr_lens[type].len
+ );
+ return -EINVAL;
+ }
+
+ switch (type) {
+ case OVS_NSH_KEY_ATTR_BASE: {
+ const struct ovs_nsh_key_base *base =
+ (struct ovs_nsh_key_base *)nla_data(a);
+ flags = base->flags;
+ ttl = base->ttl;
+ nsh->np = base->np;
+ nsh->mdtype = base->mdtype;
+ nsh->path_hdr = base->path_hdr;
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD1: {
+ const struct ovs_nsh_key_md1 *md1 =
+ (struct ovs_nsh_key_md1 *)nla_data(a);
+ struct nsh_md1_ctx *md1_dst = &nsh->md1;
+
+ has_md1 = true;
+ mdlen = nla_len(a);
+ if (((mdlen + NSH_BASE_HDR_LEN) != NSH_M_TYPE1_LEN) ||
+ ((mdlen + NSH_BASE_HDR_LEN) > size) ||
+ (mdlen <= 0)) {
+ OVS_NLERR(
+ 1,
+ "length %d of nsh attr %d is invalid",
+ mdlen,
+ type
+ );
+ return -EINVAL;
+ }
+ memcpy(md1_dst, md1, mdlen);
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD2: {
+ const struct u8 *md2 = nla_data(a);
+ struct nsh_md2_tlv *md2_dst = &nsh->md2;
+
+ has_md2 = true;
+ mdlen = nla_len(a);
+ if (((mdlen + NSH_BASE_HDR_LEN) > size) ||
+ (mdlen <= 0)) {
+ OVS_NLERR(
+ 1,
+ "length %d of nsh attr %d is invalid",
+ mdlen,
+ type
+ );
+ return -EINVAL;
+ }
+ memcpy(md2_dst, md2, mdlen);
+ break;
+ }
+ default:
+ OVS_NLERR(1, "Unknown nsh attribute %d",
+ type);
+ return -EINVAL;
+ }
+ }
+
+ if (rem > 0) {
+ OVS_NLERR(1, "nsh attribute has %d unknown bytes.", rem);
+ return -EINVAL;
+ }
+
+ if ((has_md1 && nsh->mdtype != NSH_M_TYPE1) ||
+ (has_md2 && nsh->mdtype != NSH_M_TYPE2)) {
+ OVS_NLERR(1,
+ "nsh attribute has unmatched MD type %d.",
+ nsh->mdtype);
+ return -EINVAL;
+ }
+
+ if (unlikely(has_md1 && has_md2)) {
+ OVS_NLERR(1, "both nsh md1 and md2 attribute are there");
+ return -EINVAL;
+ }
+
+ if (unlikely(!has_md1 && !has_md2)) {
+ OVS_NLERR(1, "neither nsh md1 nor md2 attribute is there");
+ return -EINVAL;
+ }
+
+ /* nsh header length = NSH_BASE_HDR_LEN + mdlen */
+ len = NSH_BASE_HDR_LEN + mdlen;
+ nsh_set_flags_ttl_len(nsh, flags, ttl, len);
+
+ return 0;
+}
+
+int nsh_key_from_nlattr(const struct nlattr *attr,
+ struct ovs_key_nsh *nsh)
+{
+ struct nlattr *a;
+ int rem;
+ bool has_md1 = false;
+
+ nla_for_each_nested(a, attr, rem) {
+ int type = nla_type(a);
+
+ if (type > OVS_NSH_KEY_ATTR_MAX) {
+ OVS_NLERR(1, "nsh attr %d is out of range max %d",
+ type, OVS_NSH_KEY_ATTR_MAX);
+ return -EINVAL;
+ }
+
+ if (!check_attr_len(nla_len(a),
+ ovs_nsh_key_attr_lens[type].len)) {
+ OVS_NLERR(
+ 1,
+ "nsh attr %d has unexpected len %d expected %d",
+ type,
+ nla_len(a),
+ ovs_nsh_key_attr_lens[type].len
+ );
+ return -EINVAL;
+ }
+
+ switch (type) {
+ case OVS_NSH_KEY_ATTR_BASE: {
+ const struct ovs_nsh_key_base *base =
+ (struct ovs_nsh_key_base *)nla_data(a);
+
+ memcpy(nsh, base, sizeof(*base));
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD1: {
+ const struct ovs_nsh_key_md1 *md1 =
+ (struct ovs_nsh_key_md1 *)nla_data(a);
+
+ has_md1 = true;
+ memcpy(nsh->context, md1->context, sizeof(*md1));
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD2:
+ /* Not supported yet */
+ return -ENOTSUPP;
+ default:
+ OVS_NLERR(1, "Unknown nsh attribute %d",
+ type);
+ return -EINVAL;
+ }
+ }
+
+ if (rem > 0) {
+ OVS_NLERR(1, "nsh attribute has %d unknown bytes.", rem);
+ return -EINVAL;
+ }
+
+ if ((has_md1 && nsh->mdtype != NSH_M_TYPE1)) {
+ OVS_NLERR(1, "nsh attribute has unmatched MD type %d.",
+ nsh->mdtype);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int nsh_key_put_from_nlattr(const struct nlattr *attr,
+ struct sw_flow_match *match, bool is_mask,
+ bool is_push_nsh, bool log)
+{
+ struct nlattr *a;
+ int rem;
+ bool has_md1 = false;
+ bool has_md2 = false;
+ u8 mdtype = 0;
+ int mdlen = 0;
+
+ nla_for_each_nested(a, attr, rem) {
+ int type = nla_type(a);
+ int i;
+
+ if (type > OVS_NSH_KEY_ATTR_MAX) {
+ OVS_NLERR(log, "nsh attr %d is out of range max %d",
+ type, OVS_NSH_KEY_ATTR_MAX);
+ return -EINVAL;
+ }
+
+ if (!check_attr_len(nla_len(a),
+ ovs_nsh_key_attr_lens[type].len)) {
+ OVS_NLERR(
+ log,
+ "nsh attr %d has unexpected len %d expected %d",
+ type,
+ nla_len(a),
+ ovs_nsh_key_attr_lens[type].len
+ );
+ return -EINVAL;
+ }
+
+ switch (type) {
+ case OVS_NSH_KEY_ATTR_BASE: {
+ const struct ovs_nsh_key_base *base =
+ (struct ovs_nsh_key_base *)nla_data(a);
+
+ mdtype = base->mdtype;
+ SW_FLOW_KEY_PUT(match, nsh.flags,
+ base->flags, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.ttl,
+ base->ttl, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.mdtype,
+ base->mdtype, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.np,
+ base->np, is_mask);
+ SW_FLOW_KEY_PUT(match, nsh.path_hdr,
+ base->path_hdr, is_mask);
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD1: {
+ const struct ovs_nsh_key_md1 *md1 =
+ (struct ovs_nsh_key_md1 *)nla_data(a);
+
+ has_md1 = true;
+ for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++)
+ SW_FLOW_KEY_PUT(match, nsh.context[i],
+ md1->context[i], is_mask);
+ break;
+ }
+ case OVS_NSH_KEY_ATTR_MD2:
+ if (!is_push_nsh) /* Not supported MD type 2 yet */
+ return -ENOTSUPP;
+
+ has_md2 = true;
+ mdlen = nla_len(a);
+ if ((mdlen > NSH_CTX_HDRS_MAX_LEN) ||
+ (mdlen <= 0))
+ return -EINVAL;
+ break;
+ default:
+ OVS_NLERR(log, "Unknown nsh attribute %d",
+ type);
+ return -EINVAL;
+ }
+ }
+
+ if (rem > 0) {
+ OVS_NLERR(log, "nsh attribute has %d unknown bytes.", rem);
+ return -EINVAL;
+ }
+
+ if (!is_mask) {
+ if ((has_md1 && mdtype != NSH_M_TYPE1)) {
+ OVS_NLERR(1, "nsh attribute has unmatched MD type %d.",
+ mdtype);
+ return -EINVAL;
+ }
+ }
+
+ if (is_push_nsh & !is_mask) {
+ if ((has_md1 && mdtype != NSH_M_TYPE1) ||
+ (has_md2 && mdtype != NSH_M_TYPE2) ||
+ (has_md1 && has_md2) ||
+ (!has_md1 && !has_md2)) {
+ OVS_NLERR(
+ 1,
+ "push nsh attributes are invalid for type %d.",
+ mdtype
+ );
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match,
u64 attrs, const struct nlattr **a,
bool is_mask, bool log)
@@ -1306,6 +1631,13 @@ static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match,
attrs &= ~(1 << OVS_KEY_ATTR_ARP);
}
+ if (attrs & (1 << OVS_KEY_ATTR_NSH)) {
+ if (nsh_key_put_from_nlattr(a[OVS_KEY_ATTR_NSH], match,
+ is_mask, false, log) < 0)
+ return -EINVAL;
+ attrs &= ~(1 << OVS_KEY_ATTR_NSH);
+ }
+
if (attrs & (1 << OVS_KEY_ATTR_MPLS)) {
const struct ovs_key_mpls *mpls_key;
@@ -1622,6 +1954,40 @@ static int ovs_nla_put_vlan(struct sk_buff *skb, const struct vlan_head *vh,
return 0;
}
+static int nsh_key_to_nlattr(const struct ovs_key_nsh *nsh, bool is_mask,
+ struct sk_buff *skb)
+{
+ struct nlattr *start;
+ struct ovs_nsh_key_base base;
+ struct ovs_nsh_key_md1 md1;
+
+ memcpy(&base, nsh, sizeof(base));
+
+ if (is_mask || nsh->mdtype == NSH_M_TYPE1)
+ memcpy(md1.context, nsh->context, sizeof(md1));
+
+ start = nla_nest_start(skb, OVS_KEY_ATTR_NSH);
+ if (!start)
+ return -EMSGSIZE;
+
+ if (nla_put(skb, OVS_NSH_KEY_ATTR_BASE, sizeof(base), &base))
+ goto nla_put_failure;
+
+ if (is_mask || nsh->mdtype == NSH_M_TYPE1) {
+ if (nla_put(skb, OVS_NSH_KEY_ATTR_MD1, sizeof(md1), &md1))
+ goto nla_put_failure;
+ }
+
+ /* Don't support MD type 2 yet */
+
+ nla_nest_end(skb, start);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
const struct sw_flow_key *output, bool is_mask,
struct sk_buff *skb)
@@ -1750,6 +2116,9 @@ static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
ipv6_key->ipv6_tclass = output->ip.tos;
ipv6_key->ipv6_hlimit = output->ip.ttl;
ipv6_key->ipv6_frag = output->ip.frag;
+ } else if (swkey->eth.type == htons(ETH_P_NSH)) {
+ if (nsh_key_to_nlattr(&output->nsh, is_mask, skb))
+ goto nla_put_failure;
} else if (swkey->eth.type == htons(ETH_P_ARP) ||
swkey->eth.type == htons(ETH_P_RARP)) {
struct ovs_key_arp *arp_key;
@@ -2242,6 +2611,19 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
return err;
}
+static bool validate_nsh(const struct nlattr *attr, bool is_mask,
+ bool is_push_nsh, bool log)
+{
+ struct sw_flow_match match;
+ struct sw_flow_key key;
+ int ret = 0;
+
+ ovs_match_init(&match, &key, true, NULL);
+ ret = nsh_key_put_from_nlattr(attr, &match, is_mask,
+ is_push_nsh, log);
+ return ((ret != 0) ? false : true);
+}
+
/* Return false if there are any non-masked bits set.
* Mask follows data immediately, before any netlink padding.
*/
@@ -2384,6 +2766,11 @@ static int validate_set(const struct nlattr *a,
break;
+ case OVS_KEY_ATTR_NSH:
+ if (!validate_nsh(nla_data(a), masked, false, log))
+ return -EINVAL;
+ break;
+
default:
return -EINVAL;
}
@@ -2482,6 +2869,8 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
[OVS_ACTION_ATTR_TRUNC] = sizeof(struct ovs_action_trunc),
[OVS_ACTION_ATTR_PUSH_ETH] = sizeof(struct ovs_action_push_eth),
[OVS_ACTION_ATTR_POP_ETH] = 0,
+ [OVS_ACTION_ATTR_PUSH_NSH] = (u32)-1,
+ [OVS_ACTION_ATTR_POP_NSH] = 0,
};
const struct ovs_action_push_vlan *vlan;
int type = nla_type(a);
@@ -2636,6 +3025,19 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
mac_proto = MAC_PROTO_ETHERNET;
break;
+ case OVS_ACTION_ATTR_PUSH_NSH:
+ mac_proto = MAC_PROTO_NONE;
+ if (!validate_nsh(nla_data(a), false, true, true))
+ return -EINVAL;
+ break;
+
+ case OVS_ACTION_ATTR_POP_NSH:
+ if (key->nsh.np == NSH_P_ETHERNET)
+ mac_proto = MAC_PROTO_ETHERNET;
+ else
+ mac_proto = MAC_PROTO_NONE;
+ break;
+
default:
OVS_NLERR(log, "Unknown Action type %d", type);
return -EINVAL;
diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h
index 929c665..a849945 100644
--- a/net/openvswitch/flow_netlink.h
+++ b/net/openvswitch/flow_netlink.h
@@ -79,4 +79,8 @@ int ovs_nla_put_actions(const struct nlattr *attr,
void ovs_nla_free_flow_actions(struct sw_flow_actions *);
void ovs_nla_free_flow_actions_rcu(struct sw_flow_actions *);
+int nsh_key_from_nlattr(const struct nlattr *attr, struct ovs_key_nsh *nsh);
+int nsh_hdr_from_nlattr(const struct nlattr *attr, struct nsh_hdr *nsh_src,
+ size_t size);
+
#endif /* flow_netlink.h */
--
2.5.5
^ permalink raw reply related
* Re: [PATCH] pktgen: add a new sample script for 40G and above link testing
From: Waskiewicz Jr, Peter @ 2017-08-25 14:24 UTC (permalink / raw)
To: Jesper Dangaard Brouer, Hu, Robert
Cc: robert.hu@linux.intel.com, netdev@vger.kernel.org
In-Reply-To: <20170825111921.061713c8@redhat.com>
On 8/25/17 5:19 AM, Jesper Dangaard Brouer wrote:
>>
>> Tested with Intel XL710 NIC with Cisco 3172 switch.
>>
>> It would be even slightly better if the irqbalance service is turned
>> off outside.
>
> Yes, if you don't turn-off (kill) irqbalance it will move around the
> IRQs behind your back...
Or you can use the --banirq option to irqbalance to ignore your device's
interrupts as targets for balancing.
Cheers,
-PJ
^ permalink raw reply
* [PATCH net-next v6 2/3] net: gso: Add GSO support for NSH
From: Yi Yang @ 2017-08-25 14:20 UTC (permalink / raw)
To: netdev; +Cc: dev, jbenc, e, blp, jan.scheurich, Yi Yang
In-Reply-To: <1503670805-31051-1-git-send-email-yi.y.yang@intel.com>
NSH (Network Service Header)[1] is a new protocol for service
function chaining, it can be handled as a L3 protocol like
IPv4 and IPv6, Eth + NSH + Inner packet or VxLAN-gpe + NSH +
Inner packet are two typical use cases.
We need to enbale Open vSwitch to support NSH, this patch
is to make Linux network infrastructure able to support
NSH GSO for big packet.
[1] https://datatracker.ietf.org/doc/draft-ietf-sfc-nsh/
Signed-off-by: Yi Yang <yi.y.yang@intel.com>
---
include/linux/netdevice.h | 1 +
include/linux/skbuff.h | 8 +++-
net/Kconfig | 1 +
net/Makefile | 1 +
net/core/dev.c | 14 ++++++
net/ipv4/udp_offload.c | 7 +++
net/nsh/Kconfig | 11 +++++
net/nsh/Makefile | 4 ++
net/nsh/nsh_gso.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 151 insertions(+), 2 deletions(-)
create mode 100644 net/nsh/Kconfig
create mode 100644 net/nsh/Makefile
create mode 100644 net/nsh/nsh_gso.c
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c5475b3..b017418 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3253,6 +3253,7 @@ struct sk_buff *napi_get_frags(struct napi_struct *napi);
gro_result_t napi_gro_frags(struct napi_struct *napi);
struct packet_offload *gro_find_receive_by_type(__be16 type);
struct packet_offload *gro_find_complete_by_type(__be16 type);
+struct packet_offload *find_gso_segment_by_type(__be16 type);
static inline void napi_free_frags(struct napi_struct *napi)
{
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 7594e19..aafc8ff 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -766,7 +766,7 @@ struct sk_buff {
__u8 ndisc_nodetype:2;
#endif
__u8 ipvs_property:1;
- __u8 inner_protocol_type:1;
+ __u8 inner_protocol_type:2;
__u8 remcsum_offload:1;
#ifdef CONFIG_NET_SWITCHDEV
__u8 offload_fwd_mark:1;
@@ -2174,12 +2174,16 @@ static inline void skb_tailroom_reserve(struct sk_buff *skb, unsigned int mtu,
#define ENCAP_TYPE_ETHER 0
#define ENCAP_TYPE_IPPROTO 1
+#define ENCAP_TYPE_NSH 2
static inline void skb_set_inner_protocol(struct sk_buff *skb,
__be16 protocol)
{
skb->inner_protocol = protocol;
- skb->inner_protocol_type = ENCAP_TYPE_ETHER;
+ if (skb->inner_protocol == htons(ETH_P_NSH))
+ skb->inner_protocol_type = ENCAP_TYPE_NSH;
+ else
+ skb->inner_protocol_type = ENCAP_TYPE_ETHER;
}
static inline void skb_set_inner_ipproto(struct sk_buff *skb,
diff --git a/net/Kconfig b/net/Kconfig
index 7d57ef3..818df7a 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -240,6 +240,7 @@ source "net/switchdev/Kconfig"
source "net/l3mdev/Kconfig"
source "net/qrtr/Kconfig"
source "net/ncsi/Kconfig"
+source "net/nsh/Kconfig"
config RPS
bool
diff --git a/net/Makefile b/net/Makefile
index bed80fa..82bfac6 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -85,3 +85,4 @@ obj-y += l3mdev/
endif
obj-$(CONFIG_QRTR) += qrtr/
obj-$(CONFIG_NET_NCSI) += ncsi/
+obj-$(CONFIG_NET_NSH_GSO) += nsh/
diff --git a/net/core/dev.c b/net/core/dev.c
index 270b547..02a988d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4874,6 +4874,20 @@ struct packet_offload *gro_find_complete_by_type(__be16 type)
}
EXPORT_SYMBOL(gro_find_complete_by_type);
+struct packet_offload *find_gso_segment_by_type(__be16 type)
+{
+ struct list_head *offload_head = &offload_base;
+ struct packet_offload *ptype;
+
+ list_for_each_entry_rcu(ptype, offload_head, list) {
+ if (ptype->type != type || !ptype->callbacks.gso_segment)
+ continue;
+ return ptype;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(find_gso_segment_by_type);
+
static void napi_skb_free_stolen_head(struct sk_buff *skb)
{
skb_dst_drop(skb);
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 97658bf..31f9383 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -155,6 +155,7 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
__be16 protocol = skb->protocol;
const struct net_offload **offloads;
const struct net_offload *ops;
+ const struct packet_offload *po;
struct sk_buff *segs = ERR_PTR(-EINVAL);
struct sk_buff *(*gso_inner_segment)(struct sk_buff *skb,
netdev_features_t features);
@@ -173,6 +174,12 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
goto out_unlock;
gso_inner_segment = ops->callbacks.gso_segment;
break;
+ case ENCAP_TYPE_NSH:
+ protocol = skb->inner_protocol;
+ po = find_gso_segment_by_type(protocol);
+ if (!po || !po->callbacks.gso_segment)
+ goto out_unlock;
+ gso_inner_segment = po->callbacks.gso_segment;
default:
goto out_unlock;
}
diff --git a/net/nsh/Kconfig b/net/nsh/Kconfig
new file mode 100644
index 0000000..0157b26
--- /dev/null
+++ b/net/nsh/Kconfig
@@ -0,0 +1,11 @@
+#
+# NSH GSO support
+#
+
+config NET_NSH_GSO
+ bool "NSH GSO support"
+ depends on INET
+ default y
+ ---help---
+ This allows segmentation of GSO packet that have had NSH header
+ pushed onto them and thus become NSH GSO packets.
diff --git a/net/nsh/Makefile b/net/nsh/Makefile
new file mode 100644
index 0000000..eb4bca0
--- /dev/null
+++ b/net/nsh/Makefile
@@ -0,0 +1,4 @@
+#
+# Makefile for NSH GSO.
+#
+obj-$(CONFIG_NET_NSH_GSO) += nsh_gso.o
diff --git a/net/nsh/nsh_gso.c b/net/nsh/nsh_gso.c
new file mode 100644
index 0000000..4b6fb29
--- /dev/null
+++ b/net/nsh/nsh_gso.c
@@ -0,0 +1,106 @@
+/*
+ * NSH GSO Support
+ *
+ * Authors: Yi Yang (yi.y.yang@intel.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Based on: net/mpls/mpls_gso.c
+ */
+
+#include <linux/err.h>
+#include <linux/netdev_features.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <net/protocol.h>
+#include <net/nsh.h>
+
+struct sk_buff *nsh_gso_segment(struct sk_buff *skb,
+ netdev_features_t features)
+{
+ struct sk_buff *segs = ERR_PTR(-EINVAL);
+ int nshoff;
+ __be16 inner_proto;
+ struct nsh_hdr *nsh;
+ unsigned int nsh_hlen;
+ struct packet_offload *po;
+ struct sk_buff *(*gso_inner_segment)(struct sk_buff *skb,
+ netdev_features_t features);
+
+ skb_reset_network_header(skb);
+ nshoff = skb_network_header(skb) - skb_mac_header(skb);
+
+ if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN)))
+ goto out;
+
+ nsh = (struct nsh_hdr *)skb_network_header(skb);
+ nsh_hlen = nsh_hdr_len(nsh);
+ if (unlikely(!pskb_may_pull(skb, nsh_hlen)))
+ goto out;
+
+ nsh = (struct nsh_hdr *)skb_network_header(skb);
+ __skb_pull(skb, nsh_hlen);
+
+ skb_reset_transport_header(skb);
+
+ switch (nsh->np) {
+ case NSH_P_ETHERNET:
+ inner_proto = htons(ETH_P_TEB);
+ gso_inner_segment = skb_mac_gso_segment;
+ break;
+ case NSH_P_IPV4:
+ inner_proto = htons(ETH_P_IP);
+ po = find_gso_segment_by_type(inner_proto);
+ if (!po || !po->callbacks.gso_segment)
+ goto out;
+ gso_inner_segment = po->callbacks.gso_segment;
+ break;
+ case NSH_P_IPV6:
+ inner_proto = htons(ETH_P_IPV6);
+ po = find_gso_segment_by_type(inner_proto);
+ if (!po || !po->callbacks.gso_segment)
+ goto out;
+ gso_inner_segment = po->callbacks.gso_segment;
+ break;
+ case NSH_P_NSH:
+ inner_proto = htons(ETH_P_NSH);
+ gso_inner_segment = nsh_gso_segment;
+ break;
+ default:
+ goto out;
+ }
+
+ segs = gso_inner_segment(skb, features);
+ if (IS_ERR_OR_NULL(segs))
+ goto out;
+
+ skb = segs;
+ do {
+ nsh = (struct nsh_hdr *)(skb_mac_header(skb) + nshoff);
+ skb->network_header = (u8 *)nsh - skb->head;
+ } while ((skb = skb->next));
+
+out:
+ return segs;
+}
+EXPORT_SYMBOL(nsh_gso_segment);
+
+static struct packet_offload nsh_offload __read_mostly = {
+ .type = cpu_to_be16(ETH_P_NSH),
+ .priority = 15,
+ .callbacks = {
+ .gso_segment = nsh_gso_segment,
+ },
+};
+
+static int __init nsh_gso_init(void)
+{
+ dev_add_offload(&nsh_offload);
+
+ return 0;
+}
+
+device_initcall(nsh_gso_init);
--
2.5.5
^ permalink raw reply related
* [PATCH net-next v6 1/3] net: add NSH header structures and helpers
From: Yi Yang @ 2017-08-25 14:20 UTC (permalink / raw)
To: netdev; +Cc: dev, jbenc, e, blp, jan.scheurich, Yi Yang
In-Reply-To: <1503670805-31051-1-git-send-email-yi.y.yang@intel.com>
NSH (Network Service Header)[1] is a new protocol for service
function chaining, it can be handled as a L3 protocol like
IPv4 and IPv6, Eth + NSH + Inner packet or VxLAN-gpe + NSH +
Inner packet are two typical use cases.
This patch adds NSH header structures and helpers for NSH GSO
support and Open vSwitch NSH support.
[1] https://datatracker.ietf.org/doc/draft-ietf-sfc-nsh/
Signed-off-by: Yi Yang <yi.y.yang@intel.com>
---
include/net/nsh.h | 307 ++++++++++++++++++++++++++++++++++++++++++
include/uapi/linux/if_ether.h | 1 +
2 files changed, 308 insertions(+)
create mode 100644 include/net/nsh.h
diff --git a/include/net/nsh.h b/include/net/nsh.h
new file mode 100644
index 0000000..72d62df
--- /dev/null
+++ b/include/net/nsh.h
@@ -0,0 +1,307 @@
+#ifndef __NET_NSH_H
+#define __NET_NSH_H 1
+
+/*
+ * Network Service Header:
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |Ver|O|U| TTL | Length |U|U|U|U|MD Type| Next Protocol |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Service Path Identifier (SPI) | Service Index |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * ~ Mandatory/Optional Context Headers ~
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Version: The version field is used to ensure backward compatibility
+ * going forward with future NSH specification updates. It MUST be set
+ * to 0x0 by the sender, in this first revision of NSH. Given the
+ * widespread implementation of existing hardware that uses the first
+ * nibble after an MPLS label stack for ECMP decision processing, this
+ * document reserves version 01b and this value MUST NOT be used in
+ * future versions of the protocol. Please see [RFC7325] for further
+ * discussion of MPLS-related forwarding requirements.
+ *
+ * O bit: Setting this bit indicates an Operations, Administration, and
+ * Maintenance (OAM) packet. The actual format and processing of SFC
+ * OAM packets is outside the scope of this specification (see for
+ * example [I-D.ietf-sfc-oam-framework] for one approach).
+ *
+ * The O bit MUST be set for OAM packets and MUST NOT be set for non-OAM
+ * packets. The O bit MUST NOT be modified along the SFP.
+ *
+ * SF/SFF/SFC Proxy/Classifier implementations that do not support SFC
+ * OAM procedures SHOULD discard packets with O bit set, but MAY support
+ * a configurable parameter to enable forwarding received SFC OAM
+ * packets unmodified to the next element in the chain. Forwarding OAM
+ * packets unmodified by SFC elements that do not support SFC OAM
+ * procedures may be acceptable for a subset of OAM functions, but can
+ * result in unexpected outcomes for others, thus it is recommended to
+ * analyze the impact of forwarding an OAM packet for all OAM functions
+ * prior to enabling this behavior. The configurable parameter MUST be
+ * disabled by default.
+ *
+ * TTL: Indicates the maximum SFF hops for an SFP. This field is used
+ * for service plane loop detection. The initial TTL value SHOULD be
+ * configurable via the control plane; the configured initial value can
+ * be specific to one or more SFPs. If no initial value is explicitly
+ * provided, the default initial TTL value of 63 MUST be used. Each SFF
+ * involved in forwarding an NSH packet MUST decrement the TTL value by
+ * 1 prior to NSH forwarding lookup. Decrementing by 1 from an incoming
+ * value of 0 shall result in a TTL value of 63. The packet MUST NOT be
+ * forwarded if TTL is, after decrement, 0.
+ *
+ * All other flag fields, marked U, are unassigned and available for
+ * future use, see Section 11.2.1. Unassigned bits MUST be set to zero
+ * upon origination, and MUST be ignored and preserved unmodified by
+ * other NSH supporting elements. Elements which do not understand the
+ * meaning of any of these bits MUST NOT modify their actions based on
+ * those unknown bits.
+ *
+ * Length: The total length, in 4-byte words, of NSH including the Base
+ * Header, the Service Path Header, the Fixed Length Context Header or
+ * Variable Length Context Header(s). The length MUST be 0x6 for MD
+ * Type equal to 0x1, and MUST be 0x2 or greater for MD Type equal to
+ * 0x2. The length of the NSH header MUST be an integer multiple of 4
+ * bytes, thus variable length metadata is always padded out to a
+ * multiple of 4 bytes.
+ *
+ * MD Type: Indicates the format of NSH beyond the mandatory Base Header
+ * and the Service Path Header. MD Type defines the format of the
+ * metadata being carried.
+ *
+ * 0x0 - This is a reserved value. Implementations SHOULD silently
+ * discard packets with MD Type 0x0.
+ *
+ * 0x1 - This indicates that the format of the header includes a fixed
+ * length Context Header (see Figure 4 below).
+ *
+ * 0x2 - This does not mandate any headers beyond the Base Header and
+ * Service Path Header, but may contain optional variable length Context
+ * Header(s). The semantics of the variable length Context Header(s)
+ * are not defined in this document. The format of the optional
+ * variable length Context Headers is provided in Section 2.5.1.
+ *
+ * 0xF - This value is reserved for experimentation and testing, as per
+ * [RFC3692]. Implementations not explicitly configured to be part of
+ * an experiment SHOULD silently discard packets with MD Type 0xF.
+ *
+ * Next Protocol: indicates the protocol type of the encapsulated data.
+ * NSH does not alter the inner payload, and the semantics on the inner
+ * protocol remain unchanged due to NSH service function chaining.
+ * Please see the IANA Considerations section below, Section 11.2.5.
+ *
+ * This document defines the following Next Protocol values:
+ *
+ * 0x1: IPv4
+ * 0x2: IPv6
+ * 0x3: Ethernet
+ * 0x4: NSH
+ * 0x5: MPLS
+ * 0xFE: Experiment 1
+ * 0xFF: Experiment 2
+ *
+ * Packets with Next Protocol values not supported SHOULD be silently
+ * dropped by default, although an implementation MAY provide a
+ * configuration parameter to forward them. Additionally, an
+ * implementation not explicitly configured for a specific experiment
+ * [RFC3692] SHOULD silently drop packets with Next Protocol values 0xFE
+ * and 0xFF.
+ *
+ * Service Path Identifier (SPI): Identifies a service path.
+ * Participating nodes MUST use this identifier for Service Function
+ * Path selection. The initial classifier MUST set the appropriate SPI
+ * for a given classification result.
+ *
+ * Service Index (SI): Provides location within the SFP. The initial
+ * classifier for a given SFP SHOULD set the SI to 255, however the
+ * control plane MAY configure the initial value of SI as appropriate
+ * (i.e., taking into account the length of the service function path).
+ * The Service Index MUST be decremented by a value of 1 by Service
+ * Functions or by SFC Proxy nodes after performing required services
+ * and the new decremented SI value MUST be used in the egress packet's
+ * NSH. The initial Classifier MUST send the packet to the first SFF in
+ * the identified SFP for forwarding along an SFP. If re-classification
+ * occurs, and that re-classification results in a new SPI, the
+ * (re)classifier is, in effect, the initial classifier for the
+ * resultant SPI.
+ *
+ * The SI is used in conjunction the with Service Path Identifier for
+ * Service Function Path Selection and for determining the next SFF/SF
+ * in the path. The SI is also valuable when troubleshooting or
+ * reporting service paths. Additionally, while the TTL field is the
+ * main mechanism for service plane loop detection, the SI can also be
+ * used for detecting service plane loops.
+ *
+ * When the Base Header specifies MD Type = 0x1, a Fixed Length Context
+ * Header (16-bytes) MUST be present immediately following the Service
+ * Path Header. The value of a Fixed Length Context
+ * Header that carries no metadata MUST be set to zero.
+ *
+ * When the base header specifies MD Type = 0x2, zero or more Variable
+ * Length Context Headers MAY be added, immediately following the
+ * Service Path Header (see Figure 5). Therefore, Length = 0x2,
+ * indicates that only the Base Header followed by the Service Path
+ * Header are present. The optional Variable Length Context Headers
+ * MUST be of an integer number of 4-bytes. The base header Length
+ * field MUST be used to determine the offset to locate the original
+ * packet or frame for SFC nodes that require access to that
+ * information.
+ *
+ * The format of the optional variable length Context Headers
+ *
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Metadata Class | Type |U| Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Variable Metadata |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Metadata Class (MD Class): Defines the scope of the 'Type' field to
+ * provide a hierarchical namespace. The IANA Considerations
+ * Section 11.2.4 defines how the MD Class values can be allocated to
+ * standards bodies, vendors, and others.
+ *
+ * Type: Indicates the explicit type of metadata being carried. The
+ * definition of the Type is the responsibility of the MD Class owner.
+ *
+ * Unassigned bit: One unassigned bit is available for future use. This
+ * bit MUST NOT be set, and MUST be ignored on receipt.
+ *
+ * Length: Indicates the length of the variable metadata, in bytes. In
+ * case the metadata length is not an integer number of 4-byte words,
+ * the sender MUST add pad bytes immediately following the last metadata
+ * byte to extend the metadata to an integer number of 4-byte words.
+ * The receiver MUST round up the length field to the nearest 4-byte
+ * word boundary, to locate and process the next field in the packet.
+ * The receiver MUST access only those bytes in the metadata indicated
+ * by the length field (i.e., actual number of bytes) and MUST ignore
+ * the remaining bytes up to the nearest 4-byte word boundary. The
+ * Length may be 0 or greater.
+ *
+ * A value of 0 denotes a Context Header without a Variable Metadata
+ * field.
+ *
+ * [0] https://datatracker.ietf.org/doc/draft-ietf-sfc-nsh/
+ */
+
+/**
+ * struct nsh_md1_ctx - Keeps track of NSH context data
+ * @nshc<1-4>: NSH Contexts.
+ */
+struct nsh_md1_ctx {
+ __be32 context[4];
+};
+
+struct nsh_md2_tlv {
+ __be16 md_class;
+ u8 type;
+ u8 length;
+ u8 md_value[];
+};
+
+struct nsh_hdr {
+ __be16 ver_flags_ttl_len;
+ u8 mdtype;
+ u8 np;
+ __be32 path_hdr;
+ union {
+ struct nsh_md1_ctx md1;
+ struct nsh_md2_tlv md2;
+ };
+};
+
+/* Masking NSH header fields. */
+#define NSH_VER_MASK 0xc000
+#define NSH_VER_SHIFT 14
+#define NSH_FLAGS_MASK 0x3000
+#define NSH_FLAGS_SHIFT 12
+#define NSH_TTL_MASK 0x0fc0
+#define NSH_TTL_SHIFT 6
+#define NSH_LEN_MASK 0x003f
+#define NSH_LEN_SHIFT 0
+
+#define NSH_MDTYPE_MASK 0x0f
+#define NSH_MDTYPE_SHIFT 0
+
+#define NSH_SPI_MASK 0xffffff00
+#define NSH_SPI_SHIFT 8
+#define NSH_SI_MASK 0x000000ff
+#define NSH_SI_SHIFT 0
+
+/* NSH Base Header Next Protocol. */
+#define NSH_P_IPV4 0x01
+#define NSH_P_IPV6 0x02
+#define NSH_P_ETHERNET 0x03
+#define NSH_P_NSH 0x04
+#define NSH_P_MPLS 0x05
+
+/* MD Type Registry. */
+#define NSH_M_TYPE1 0x01
+#define NSH_M_TYPE2 0x02
+#define NSH_M_EXP1 0xFE
+#define NSH_M_EXP2 0xFF
+
+/* NSH Base Header Length */
+#define NSH_BASE_HDR_LEN 8
+
+/* NSH MD Type 1 header Length. */
+#define NSH_M_TYPE1_LEN 24
+
+/* NSH header maximum Length. */
+#define NSH_HDR_MAX_LEN 256
+
+/* NSH context headers maximum Length. */
+#define NSH_CTX_HDRS_MAX_LEN 248
+
+static inline u16 nsh_hdr_len(const struct nsh_hdr *nsh)
+{
+ return ((ntohs(nsh->ver_flags_ttl_len) & NSH_LEN_MASK)
+ >> NSH_LEN_SHIFT) << 2;
+}
+
+static inline u8 nsh_get_ver(const struct nsh_hdr *nsh)
+{
+ return (ntohs(nsh->ver_flags_ttl_len) & NSH_VER_MASK)
+ >> NSH_VER_SHIFT;
+}
+
+static inline u8 nsh_get_flags(const struct nsh_hdr *nsh)
+{
+ return (ntohs(nsh->ver_flags_ttl_len) & NSH_FLAGS_MASK)
+ >> NSH_FLAGS_SHIFT;
+}
+
+static inline u8 nsh_get_ttl(const struct nsh_hdr *nsh)
+{
+ return (ntohs(nsh->ver_flags_ttl_len) & NSH_TTL_MASK)
+ >> NSH_TTL_SHIFT;
+}
+
+static inline void __nsh_set_xflag(struct nsh_hdr *nsh, u16 xflag, u16 xmask)
+{
+ nsh->ver_flags_ttl_len
+ = (nsh->ver_flags_ttl_len & ~htons(xmask)) | htons(xflag);
+}
+
+static inline void nsh_set_flags_and_ttl(struct nsh_hdr *nsh, u8 flags, u8 ttl)
+{
+ __nsh_set_xflag(nsh, ((flags << NSH_FLAGS_SHIFT) & NSH_FLAGS_MASK) |
+ ((ttl << NSH_TTL_SHIFT) & NSH_TTL_MASK),
+ NSH_FLAGS_MASK | NSH_TTL_MASK);
+}
+
+static inline void nsh_set_flags_ttl_len(struct nsh_hdr *nsh, u8 flags,
+ u8 ttl, u8 len)
+{
+ len = len >> 2;
+ __nsh_set_xflag(nsh, ((flags << NSH_FLAGS_SHIFT) & NSH_FLAGS_MASK) |
+ ((ttl << NSH_TTL_SHIFT) & NSH_TTL_MASK) |
+ ((len << NSH_LEN_SHIFT) & NSH_LEN_MASK),
+ NSH_FLAGS_MASK | NSH_TTL_MASK | NSH_LEN_MASK);
+}
+
+#endif /* __NET_NSH_H */
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index efeb119..bc5b727 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -138,6 +138,7 @@
#define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */
#define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */
#define ETH_P_XDSA 0x00F8 /* Multiplexed DSA protocol */
+#define ETH_P_NSH 0x894F /* Ethertype for NSH. */
/*
* This is an Ethernet frame header.
--
2.5.5
^ permalink raw reply related
* [PATCH] rtlwifi: rtl8822be: Add firmware for new driver/device
From: Larry Finger @ 2017-08-25 14:23 UTC (permalink / raw)
To: linux-firmware; +Cc: linux-wireless, Larry Finger, netdev
A driver for the RTL8822BE has been added to staging. This commit supplies
the firmware for it.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
WHENCE | 9 +++++++++
rtlwifi/rtl8822befw.bin | Bin 0 -> 127496 bytes
2 files changed, 9 insertions(+)
create mode 100644 rtlwifi/rtl8822befw.bin
diff --git a/WHENCE b/WHENCE
index 00737d5..e062a35 100644
--- a/WHENCE
+++ b/WHENCE
@@ -2423,6 +2423,15 @@ Licence: Redistributable. See LICENCE.rtlwifi_firmware.txt for details.
--------------------------------------------------------------------------
+Driver: rtl8822be - Realtek 802.11n WLAN driver for RTL8822BE
+
+Info: Sent to Larry Finger by Realtek engineer Ping-Ke Shih <pkshih@realtek.com>
+File: rtlwifi/rtl8822befw.bin
+
+Licence: Redistributable. See LICENCE.rtlwifi_firmware.txt for details.
+
+--------------------------------------------------------------------------
+
Driver: rtl8192ee - Realtek 802.11n WLAN driver for RTL8192EE
Info: Initial version taken from Realtek version
diff --git a/rtlwifi/rtl8822befw.bin b/rtlwifi/rtl8822befw.bin
new file mode 100644
index 0000000000000000000000000000000000000000..1fcdbeb2dddf300be548f219065746a90b84fa21
GIT binary patch
literal 127496
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�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
literal 0
HcmV?d00001
--
2.12.3
^ permalink raw reply related
* [PATCH 5/7] RDS: make rhashtable_params const
From: Bhumika Goyal @ 2017-08-25 14:21 UTC (permalink / raw)
To: julia.lawall, marcel, gustavo, johan.hedberg, davem, pablo,
kadlec, fw, stephen, alex.aring, stefan, kuznet, yoshfuji,
santosh.shilimkar, trond.myklebust, anna.schumaker, bfields,
jlayton, linux-bluetooth, netdev, linux-kernel, netfilter-devel,
coreteam, bridge, linux-wpan, linux-rdma, rds-devel, linux-nfs
Cc: Bhumika Goyal
In-Reply-To: <1503670907-23221-1-git-send-email-bhumirks@gmail.com>
Make this const as it is either used during a copy operation or passed
to a const argument of the function rhltable_init
Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
---
net/rds/bind.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/rds/bind.c b/net/rds/bind.c
index 3a915be..75d43dc 100644
--- a/net/rds/bind.c
+++ b/net/rds/bind.c
@@ -40,7 +40,7 @@
static struct rhashtable bind_hash_table;
-static struct rhashtable_params ht_parms = {
+static const struct rhashtable_params ht_parms = {
.nelem_hint = 768,
.key_len = sizeof(u64),
.key_offset = offsetof(struct rds_sock, rs_bound_key),
--
1.9.1
^ permalink raw reply related
* [PATCH 4/7] ipv4: make net_protocol const
From: Bhumika Goyal @ 2017-08-25 14:21 UTC (permalink / raw)
To: julia.lawall, marcel, gustavo, johan.hedberg, davem, pablo,
kadlec, fw, stephen, alex.aring, stefan, kuznet, yoshfuji,
santosh.shilimkar, trond.myklebust, anna.schumaker, bfields,
jlayton, linux-bluetooth, netdev, linux-kernel, netfilter-devel,
coreteam, bridge, linux-wpan, linux-rdma, rds-devel, linux-nfs
Cc: Bhumika Goyal
In-Reply-To: <1503670907-23221-1-git-send-email-bhumirks@gmail.com>
Make these const as they are only passed to a const argument of the
function inet_add_protocol.
Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
---
net/ipv4/af_inet.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index d678820..19aee07 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1596,7 +1596,7 @@ u64 snmp_fold_field64(void __percpu *mib, int offt, size_t syncp_offset)
};
#endif
-static struct net_protocol tcp_protocol = {
+static const struct net_protocol tcp_protocol = {
.early_demux = tcp_v4_early_demux,
.early_demux_handler = tcp_v4_early_demux,
.handler = tcp_v4_rcv,
@@ -1606,7 +1606,7 @@ u64 snmp_fold_field64(void __percpu *mib, int offt, size_t syncp_offset)
.icmp_strict_tag_validation = 1,
};
-static struct net_protocol udp_protocol = {
+static const struct net_protocol udp_protocol = {
.early_demux = udp_v4_early_demux,
.early_demux_handler = udp_v4_early_demux,
.handler = udp_rcv,
--
1.9.1
^ permalink raw reply related
* [PATCH 3/7] ieee802154: 6lowpan: make header_ops const
From: Bhumika Goyal @ 2017-08-25 14:21 UTC (permalink / raw)
To: julia.lawall, marcel, gustavo, johan.hedberg, davem, pablo,
kadlec, fw, stephen, alex.aring, stefan, kuznet, yoshfuji,
santosh.shilimkar, trond.myklebust, anna.schumaker, bfields,
jlayton, linux-bluetooth, netdev, linux-kernel, netfilter-devel,
coreteam, bridge, linux-wpan, linux-rdma, rds-devel, linux-nfs
Cc: Bhumika Goyal
In-Reply-To: <1503670907-23221-1-git-send-email-bhumirks@gmail.com>
Make this const as it is only stored as a reference in a const field of
a net_device structure.
Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
---
net/ieee802154/6lowpan/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
index de2661c..974765b 100644
--- a/net/ieee802154/6lowpan/core.c
+++ b/net/ieee802154/6lowpan/core.c
@@ -54,7 +54,7 @@
static int open_count;
-static struct header_ops lowpan_header_ops = {
+static const struct header_ops lowpan_header_ops = {
.create = lowpan_header_create,
};
--
1.9.1
^ permalink raw reply related
* [PATCH 1/7] Bluetooth: 6lowpan: make header_ops const
From: Bhumika Goyal @ 2017-08-25 14:21 UTC (permalink / raw)
To: julia.lawall, marcel, gustavo, johan.hedberg, davem, pablo,
kadlec, fw, stephen, alex.aring, stefan, kuznet, yoshfuji,
santosh.shilimkar, trond.myklebust, anna.schumaker, bfields,
jlayton, linux-bluetooth, netdev, linux-kernel, netfilter-devel,
coreteam, bridge, linux-wpan, linux-rdma, rds-devel, linux-nfs
Cc: Bhumika Goyal
In-Reply-To: <1503670907-23221-1-git-send-email-bhumirks@gmail.com>
Make this const as it is only stored as a reference in a const field of
a net_device structure.
Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
---
net/bluetooth/6lowpan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 4e2576f..50fcdd1 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -581,7 +581,7 @@ static int bt_dev_init(struct net_device *dev)
.ndo_start_xmit = bt_xmit,
};
-static struct header_ops header_ops = {
+static const struct header_ops header_ops = {
.create = header_create,
};
--
1.9.1
^ permalink raw reply related
* [PATCH net] l2tp: initialise session's refcount before making it reachable
From: Guillaume Nault @ 2017-08-25 14:22 UTC (permalink / raw)
To: netdev; +Cc: James Chapman, David Miller
Sessions must be fully initialised before calling
l2tp_session_add_to_tunnel(). Otherwise, there's a short time frame
where partially initialised sessions can be accessed by external users.
Fixes: dbdbc73b4478 ("l2tp: fix duplicate session creation")
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
---
net/l2tp/l2tp_core.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index b0c2d4ae781d..f363669eae47 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1844,6 +1844,8 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
l2tp_session_set_header_len(session, tunnel->version);
+ refcount_set(&session->ref_count, 1);
+
err = l2tp_session_add_to_tunnel(tunnel, session);
if (err) {
kfree(session);
@@ -1851,10 +1853,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
return ERR_PTR(err);
}
- /* Bump the reference count. The session context is deleted
- * only when this drops to zero.
- */
- refcount_set(&session->ref_count, 1);
l2tp_tunnel_inc_refcount(tunnel);
/* Ensure tunnel socket isn't deleted */
--
2.14.1
^ permalink raw reply related
* [PATCH 7/7] SUNRPC: make kvec const
From: Bhumika Goyal @ 2017-08-25 14:21 UTC (permalink / raw)
To: julia.lawall-L2FTfq7BK8M, marcel-kz+m5ild9QBg9hUCZPvPmw,
gustavo-THi1TnShQwVAfugRpC6u6w,
johan.hedberg-Re5JQEeQqe8AvxtiuMwx3w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q, pablo-Cap9r6Oaw4JrovVCs/uTlw,
kadlec-K40Dz/62t/MgiyqX0sVFJYdd74u8MsAO,
fw-HFFVJYpyMKqzQB+pC5nmwQ,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
alex.aring-Re5JQEeQqe8AvxtiuMwx3w, stefan-JPH+aEBZ4P+UEJcrhfAQsw,
kuznet-v/Mj1YrvjDBInbfyfbPRSQ, yoshfuji-VfPWfsRibaP+Ru+s062T9g,
santosh.shilimkar-QHcLZuEGTsvQT0dZR+AlfA,
trond.myklebust-7I+n7zu2hftEKMMhf/gKZA,
anna.schumaker-HgOvQuBEEgTQT0dZR+AlfA,
bfields-uC3wQj2KruNg9hUCZPvPmw, jlayton-vpEMnDpepFuMZCB2o+C8xQ,
linux-bluetooth-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netfilter-devel-u79uwXL29TY76Z2rM5mHXA,
coreteam-Cap9r6Oaw4JrovVCs/uTlw,
bridge-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-wpan-u79uwXL29TY76Z2rM5mHXA,
linux-rdma-u79uwXL29TY76Z2rM5mHXA,
rds-devel-N0ozoZBvEnrZJqsBc5GL+g,
linux-nfs-u79uwXL29TY76Z2rM5mHXA
Cc: Bhumika Goyal
In-Reply-To: <1503670907-23221-1-git-send-email-bhumirks-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Make this const as it is only used during a copy operation.
Signed-off-by: Bhumika Goyal <bhumirks-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
net/sunrpc/xdr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index e34f4ee..a096025 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -998,7 +998,7 @@ void xdr_enter_page(struct xdr_stream *xdr, unsigned int len)
}
EXPORT_SYMBOL_GPL(xdr_enter_page);
-static struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0};
+static const struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0};
void
xdr_buf_from_iov(struct kvec *iov, struct xdr_buf *buf)
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 6/7] netfilter: nat: make rhashtable_params const
From: Bhumika Goyal @ 2017-08-25 14:21 UTC (permalink / raw)
To: julia.lawall, marcel, gustavo, johan.hedberg, davem, pablo,
kadlec, fw, stephen, alex.aring, stefan, kuznet, yoshfuji,
santosh.shilimkar, trond.myklebust, anna.schumaker, bfields,
jlayton, linux-bluetooth, netdev, linux-kernel, netfilter-devel,
coreteam, bridge, linux-wpan, linux-rdma, rds-devel, linux-nfs
Cc: Bhumika Goyal
In-Reply-To: <1503670907-23221-1-git-send-email-bhumirks@gmail.com>
Make this const as it is either used during a copy operation or passed
to a const argument of the function rhltable_init.
Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
---
net/netfilter/nf_nat_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index b1d3740..df983ea 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -198,7 +198,7 @@ static int nf_nat_bysource_cmp(struct rhashtable_compare_arg *arg,
return 0;
}
-static struct rhashtable_params nf_nat_bysource_params = {
+static const struct rhashtable_params nf_nat_bysource_params = {
.head_offset = offsetof(struct nf_conn, nat_bysource),
.obj_hashfn = nf_nat_bysource_hash,
.obj_cmpfn = nf_nat_bysource_cmp,
--
1.9.1
^ permalink raw reply related
* [PATCH 2/7] bridge: make ebt_table const
From: Bhumika Goyal @ 2017-08-25 14:21 UTC (permalink / raw)
To: julia.lawall, marcel, gustavo, johan.hedberg, davem, pablo,
kadlec, fw, stephen, alex.aring, stefan, kuznet, yoshfuji,
santosh.shilimkar, trond.myklebust, anna.schumaker, bfields,
jlayton, linux-bluetooth, netdev, linux-kernel, netfilter-devel,
coreteam, bridge, linux-wpan, linux-rdma, rds-devel, linux-nfs
Cc: Bhumika Goyal
In-Reply-To: <1503670907-23221-1-git-send-email-bhumirks@gmail.com>
Make this const as it is only passed to a const argument of the function
ebt_register_table.
Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
---
net/bridge/netfilter/ebtable_nat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
index 4ecf506..57cd5bb 100644
--- a/net/bridge/netfilter/ebtable_nat.c
+++ b/net/bridge/netfilter/ebtable_nat.c
@@ -48,7 +48,7 @@ static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
return 0;
}
-static struct ebt_table frame_nat = {
+static const struct ebt_table frame_nat = {
.name = "nat",
.table = &initial_table,
.valid_hooks = NAT_VALID_HOOKS,
--
1.9.1
^ permalink raw reply related
* [PATCH 0/7] net: make some structures const
From: Bhumika Goyal @ 2017-08-25 14:21 UTC (permalink / raw)
To: julia.lawall, marcel, gustavo, johan.hedberg, davem, pablo,
kadlec, fw, stephen, alex.aring, stefan, kuznet, yoshfuji,
santosh.shilimkar, trond.myklebust, anna.schumaker, bfields,
jlayton, linux-bluetooth, netdev, linux-kernel, netfilter-devel,
coreteam, bridge, linux-wpan, linux-rdma, rds-devel, linux-nfs
Cc: Bhumika Goyal
Make these const as they are not modified.
Bhumika Goyal (7):
Bluetooth: 6lowpan: make header_ops const
bridge: make ebt_table const
ieee802154: 6lowpan: make header_ops const
ipv4: make net_protocol const
RDS: make rhashtable_params const
netfilter: nat: make rhashtable_params const
SUNRPC: make kvec const
net/bluetooth/6lowpan.c | 2 +-
net/bridge/netfilter/ebtable_nat.c | 2 +-
net/ieee802154/6lowpan/core.c | 2 +-
net/ipv4/af_inet.c | 4 ++--
net/netfilter/nf_nat_core.c | 2 +-
net/rds/bind.c | 2 +-
net/sunrpc/xdr.c | 2 +-
7 files changed, 8 insertions(+), 8 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH net-next v6 0/3] openvswitch: add NSH support
From: Yi Yang @ 2017-08-25 14:20 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: dev-yBygre7rU0TnMu66kgdUjQ, jbenc-H+wXaHxf7aLQT0dZR+AlfA, e
v5->v6
- Fix the rest comments for v4.
- Add NSH GSO support for VxLAN-gpe + NSH and
Eth + NSH.
v4->v5
- Fix many comments by Jiri Benc and Eric Garver
for v4.
v3->v4
- Add new NSH match field ttl
- Update NSH header to the latest format
which will be final format and won't change
per its author's confirmation.
- Fix comments for v3.
v2->v3
- Change OVS_KEY_ATTR_NSH to nested key to handle
length-fixed attributes and length-variable
attriubte more flexibly.
- Remove struct ovs_action_push_nsh completely
- Add code to handle nested attribute for SET_MASKED
- Change PUSH_NSH to use the nested OVS_KEY_ATTR_NSH
to transfer NSH header data.
- Fix comments and coding style issues by Jiri and Eric
v1->v2
- Change encap_nsh and decap_nsh to push_nsh and pop_nsh
- Dynamically allocate struct ovs_action_push_nsh for
length-variable metadata.
This patch series is to enable NSH support in OVS kernel
data path, it also adds NSH GSO support for big packet.
Yi Yang (3):
net: add NSH header structures and helpers
net: gso: Add GSO support for NSH
openvswitch: enable NSH support
drivers/net/vxlan.c | 7 +
include/linux/netdevice.h | 1 +
include/linux/skbuff.h | 8 +-
include/net/nsh.h | 307 +++++++++++++++++++++++++++++
include/uapi/linux/if_ether.h | 1 +
include/uapi/linux/openvswitch.h | 28 +++
net/Kconfig | 1 +
net/Makefile | 1 +
net/core/dev.c | 14 ++
net/ipv4/udp_offload.c | 7 +
net/nsh/Kconfig | 11 ++
net/nsh/Makefile | 4 +
net/nsh/nsh_gso.c | 106 ++++++++++
net/openvswitch/actions.c | 178 +++++++++++++++++
net/openvswitch/flow.c | 55 ++++++
net/openvswitch/flow.h | 11 ++
net/openvswitch/flow_netlink.c | 404 ++++++++++++++++++++++++++++++++++++++-
net/openvswitch/flow_netlink.h | 4 +
18 files changed, 1145 insertions(+), 3 deletions(-)
create mode 100644 include/net/nsh.h
create mode 100644 net/nsh/Kconfig
create mode 100644 net/nsh/Makefile
create mode 100644 net/nsh/nsh_gso.c
--
2.5.5
^ permalink raw reply
* Re: [PATCH net v2 1/4] net: mvpp2: fix the mac address used when using PPv2.2
From: Andrew Lunn @ 2017-08-25 14:19 UTC (permalink / raw)
To: Antoine Tenart
Cc: davem, thomas.petazzoni, gregory.clement, nadavh, linux,
linux-kernel, mw, stefanc, netdev
In-Reply-To: <20170825141420.14027-2-antoine.tenart@free-electrons.com>
On Fri, Aug 25, 2017 at 04:14:17PM +0200, Antoine Tenart wrote:
> The mac address is only retrieved from h/w when using PPv2.1. Otherwise
> the variable holding it is still checked and used if it contains a valid
> value. As the variable isn't initialized to an invalid mac address
> value, we end up with random mac addresses which can be the same for all
> the ports handled by this PPv2 driver.
>
> Fixes this by initializing the h/w mac address variable to {0}, which is
> an invalid mac address value. This way the random assignation fallback
> is called and all ports end up with their own addresses.
>
> Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
> Fixes: 2697582144dd ("net: mvpp2: handle misc PPv2.1/PPv2.2 differences")
Hi Antoine
Is this patch alone sufficient to fix the problem?
Ideally, you want a minimal patch for stable, i.e. -net, and a fuller
fix can go into net-next.
Andrew
^ permalink raw reply
* Re: [PATCH] staging: rtlwifi: Improve debugging by using debugfs
From: Andrew Lunn @ 2017-08-25 14:16 UTC (permalink / raw)
To: Larry Finger
Cc: devel, Yan-Hsuan Chuang, gregkh, Birming Chiu, netdev,
Steven Ting
In-Reply-To: <1a1ca849-3aec-60e3-b5a3-98a6e095d298@lwfinger.net>
On Fri, Aug 25, 2017 at 08:47:00AM -0500, Larry Finger wrote:
> On 08/24/2017 08:54 PM, Andrew Lunn wrote:
> >netdev frowns upon debugfs. You should try to keep this altogether,
> >making it easy to throw away before the driver is moved out of
> >staging.
> >
> >You might want to look at ethtool -d. That will be accepted.
>
> Andrew,
>
> What is the problem with debugfs?
You should probably look back in the discussions on the netdev
mailling list. But basically, anything you want to export should
follow generic well defined interface, which can be used by other
drivers. debugfs tends to be a mess, a wild west, each driver doing
its own thing, not standardisation. It is O.K. for your own
development work, you can have your own out of tree patches adding in
debugfs, but such patches are unlikely to be accepted into mainline.
David has threatened to simply rip out all debugfs code from all
network drivers. There is push back on adding any new debugfs code,
and some driver writers have taken out debugfs code in their own
drivers, often replacing it with something generic all drivers can
use.
> Please suggest which driver has the best example of an ethtool -d
> implementation that we might study.
The API is very simple. In your ethtool_ops you need to function:
.get_regs_len, returns an int, the number of registers you can dump.
.get_regs returns the contents.
There are plenty of examples, e.g.:
http://elixir.free-electrons.com/linux/latest/source/drivers/net/ethernet/amd/pcnet32.c#L1436
If you need something more structured, look around, see if other
drivers have similar needs, and propose something generic.
> The first version of the debugfs changes were sent to wireless-drivers on
> July 2. Why are we first hearing of this objection nearly 2 months later?
Different reviewers tend to review different things. I personally
don't care so much who the vendor is, but look out for some specific
things i feel qualified to review. Ethernet PHYs and MDIO drivers,
drivers which make use of Ethernet PHYs, APIs which allow userspace to
write to registers, debugfs, changing MTUs, etc.
There are plenty of patches on netdev for me to review, so i don't
cast a wider net to other lists, like for example wireless-drivers.
You would of got this comment sooner or later, since you should be
posting to netdev at some point anyway. I can also imaging there is
also some reluctance to review staging code, until it is getting close
to moving out of staging.
Andrew
^ permalink raw reply
* [PATCH net v2 4/4] net: mvpp2: fallback using h/w and random mac if the dt one isn't valid
From: Antoine Tenart @ 2017-08-25 14:14 UTC (permalink / raw)
To: davem, thomas.petazzoni
Cc: Antoine Tenart, andrew, gregory.clement, nadavh, linux,
linux-kernel, mw, stefanc, netdev
In-Reply-To: <20170825141420.14027-1-antoine.tenart@free-electrons.com>
When using a mac address described in the device tree, a check is made
to see if it is valid. When it's not, no fallback is defined. This
patches tries to get the mac address from h/w (or use a random one if
the h/w one isn't valid) when the dt mac address isn't valid.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
drivers/net/ethernet/marvell/mvpp2.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 162e334fda37..2f1284f23e66 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -6504,19 +6504,20 @@ static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv,
if (dt_mac_addr && is_valid_ether_addr(dt_mac_addr)) {
*mac_from = "device tree";
ether_addr_copy(dev->dev_addr, dt_mac_addr);
- } else {
- if (priv->hw_version == MVPP21) {
- mvpp21_get_mac_address(port, hw_mac_addr);
- if (is_valid_ether_addr(hw_mac_addr)) {
- *mac_from = "hardware";
- ether_addr_copy(dev->dev_addr, hw_mac_addr);
- return;
- }
- }
+ return;
+ }
- *mac_from = "random";
- eth_hw_addr_random(dev);
+ if (priv->hw_version == MVPP21) {
+ mvpp21_get_mac_address(port, hw_mac_addr);
+ if (is_valid_ether_addr(hw_mac_addr)) {
+ *mac_from = "hardware";
+ ether_addr_copy(dev->dev_addr, hw_mac_addr);
+ return;
+ }
}
+
+ *mac_from = "random";
+ eth_hw_addr_random(dev);
}
/* Ports initialization */
--
2.13.5
^ permalink raw reply related
* [PATCH net v2 3/4] net: mvpp2: fix use of the random mac address for PPv2.2
From: Antoine Tenart @ 2017-08-25 14:14 UTC (permalink / raw)
To: davem, thomas.petazzoni
Cc: Antoine Tenart, andrew, gregory.clement, nadavh, linux,
linux-kernel, mw, stefanc, netdev
In-Reply-To: <20170825141420.14027-1-antoine.tenart@free-electrons.com>
The MAC retrieval logic is using a variable to store an h/w stored mac
address and checks this mac against invalid ones before using it. But
the mac address is only read from h/w when using PPv2.1. So when using
PPv2.2 it defaults to its init state.
This patches fixes the logic to only check if the h/w mac is valid when
actually retrieving a mac from h/w.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
drivers/net/ethernet/marvell/mvpp2.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index a1593134ed96..162e334fda37 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -6505,15 +6505,17 @@ static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv,
*mac_from = "device tree";
ether_addr_copy(dev->dev_addr, dt_mac_addr);
} else {
- if (priv->hw_version == MVPP21)
+ if (priv->hw_version == MVPP21) {
mvpp21_get_mac_address(port, hw_mac_addr);
- if (is_valid_ether_addr(hw_mac_addr)) {
- *mac_from = "hardware";
- ether_addr_copy(dev->dev_addr, hw_mac_addr);
- } else {
- *mac_from = "random";
- eth_hw_addr_random(dev);
+ if (is_valid_ether_addr(hw_mac_addr)) {
+ *mac_from = "hardware";
+ ether_addr_copy(dev->dev_addr, hw_mac_addr);
+ return;
+ }
}
+
+ *mac_from = "random";
+ eth_hw_addr_random(dev);
}
}
--
2.13.5
^ permalink raw reply related
* [PATCH net v2 2/4] net: mvpp2: move the mac retrieval/copy logic into its own function
From: Antoine Tenart @ 2017-08-25 14:14 UTC (permalink / raw)
To: davem, thomas.petazzoni
Cc: Antoine Tenart, andrew, gregory.clement, nadavh, linux,
linux-kernel, mw, stefanc, netdev
In-Reply-To: <20170825141420.14027-1-antoine.tenart@free-electrons.com>
The MAC retrieval has a quite complicated logic (which is broken). Moves
it to its own function to prepare for patches fixing its logic, so that
reviews are easier.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
drivers/net/ethernet/marvell/mvpp2.c | 45 +++++++++++++++++++++---------------
1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 4d598ca8503a..a1593134ed96 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -6492,6 +6492,31 @@ static int mvpp2_port_init(struct mvpp2_port *port)
return err;
}
+static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv,
+ struct device_node *port_node,
+ char **mac_from)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ char hw_mac_addr[ETH_ALEN] = {0};
+ const char *dt_mac_addr;
+
+ dt_mac_addr = of_get_mac_address(port_node);
+ if (dt_mac_addr && is_valid_ether_addr(dt_mac_addr)) {
+ *mac_from = "device tree";
+ ether_addr_copy(dev->dev_addr, dt_mac_addr);
+ } else {
+ if (priv->hw_version == MVPP21)
+ mvpp21_get_mac_address(port, hw_mac_addr);
+ if (is_valid_ether_addr(hw_mac_addr)) {
+ *mac_from = "hardware";
+ ether_addr_copy(dev->dev_addr, hw_mac_addr);
+ } else {
+ *mac_from = "random";
+ eth_hw_addr_random(dev);
+ }
+ }
+}
+
/* Ports initialization */
static int mvpp2_port_probe(struct platform_device *pdev,
struct device_node *port_node,
@@ -6502,9 +6527,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
struct mvpp2_port_pcpu *port_pcpu;
struct net_device *dev;
struct resource *res;
- const char *dt_mac_addr;
- const char *mac_from;
- char hw_mac_addr[ETH_ALEN] = {0};
+ char *mac_from = "";
u32 id;
int features;
int phy_mode;
@@ -6585,21 +6608,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
goto err_free_irq;
}
- dt_mac_addr = of_get_mac_address(port_node);
- if (dt_mac_addr && is_valid_ether_addr(dt_mac_addr)) {
- mac_from = "device tree";
- ether_addr_copy(dev->dev_addr, dt_mac_addr);
- } else {
- if (priv->hw_version == MVPP21)
- mvpp21_get_mac_address(port, hw_mac_addr);
- if (is_valid_ether_addr(hw_mac_addr)) {
- mac_from = "hardware";
- ether_addr_copy(dev->dev_addr, hw_mac_addr);
- } else {
- mac_from = "random";
- eth_hw_addr_random(dev);
- }
- }
+ mvpp2_port_copy_mac_addr(dev, priv, port_node, &mac_from);
port->tx_ring_size = MVPP2_MAX_TXD;
port->rx_ring_size = MVPP2_MAX_RXD;
--
2.13.5
^ permalink raw reply related
* [PATCH net v2 1/4] net: mvpp2: fix the mac address used when using PPv2.2
From: Antoine Tenart @ 2017-08-25 14:14 UTC (permalink / raw)
To: davem, thomas.petazzoni
Cc: Antoine Tenart, andrew, gregory.clement, nadavh, linux,
linux-kernel, mw, stefanc, netdev
In-Reply-To: <20170825141420.14027-1-antoine.tenart@free-electrons.com>
The mac address is only retrieved from h/w when using PPv2.1. Otherwise
the variable holding it is still checked and used if it contains a valid
value. As the variable isn't initialized to an invalid mac address
value, we end up with random mac addresses which can be the same for all
the ports handled by this PPv2 driver.
Fixes this by initializing the h/w mac address variable to {0}, which is
an invalid mac address value. This way the random assignation fallback
is called and all ports end up with their own addresses.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Fixes: 2697582144dd ("net: mvpp2: handle misc PPv2.1/PPv2.2 differences")
---
drivers/net/ethernet/marvell/mvpp2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 48d21c1e09f2..4d598ca8503a 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -6504,7 +6504,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
struct resource *res;
const char *dt_mac_addr;
const char *mac_from;
- char hw_mac_addr[ETH_ALEN];
+ char hw_mac_addr[ETH_ALEN] = {0};
u32 id;
int features;
int phy_mode;
--
2.13.5
^ permalink raw reply related
* [PATCH net v2 0/4] net: mvpp2: fix the mac address retrieval logic
From: Antoine Tenart @ 2017-08-25 14:14 UTC (permalink / raw)
To: davem, thomas.petazzoni
Cc: Antoine Tenart, andrew, gregory.clement, nadavh, linux,
linux-kernel, mw, stefanc, netdev
Hi all,
The MAC address retrieval logic was broken and when using the PPv2
driver on PPv2.2 engines I ended up using the same mac address on all
ports. This series of patches fixes this, and also tackle a possible bug
when defining the mac address in the device tree.
Patch 1/4 can be applied to relevant stable trees (4.12+).
The series applies on net/master (9b4e946ce14e).
Thanks!
Antoine
Since v1:
- Rebased onto net (was on net-next).
Antoine Tenart (4):
net: mvpp2: fix the mac address used when using PPv2.2
net: mvpp2: move the mac retrieval/copy logic into its own function
net: mvpp2: fix use of the random mac address for PPv2.2
net: mvpp2: fallback using h/w and random mac if the dt one isn't
valid
drivers/net/ethernet/marvell/mvpp2.c | 48 ++++++++++++++++++++++--------------
1 file changed, 30 insertions(+), 18 deletions(-)
--
2.13.5
^ permalink raw reply
* Possible race in nsc-ircc.ko
From: Anton Volkov @ 2017-08-25 14:05 UTC (permalink / raw)
To: dagb, jt, samuel; +Cc: netdev, linux-kernel, ldv-project, Alexey Khoroshilov
Hello.
While searching for races in the Linux kernel I've come across
"drivers/net/irda/nsc-ircc.ko" module. Here is a question that I came up
with while analyzing results. Lines are given using the info from Linux
v4.12.
Consider the following case:
Thread 1: Thread 2:
nsc_ircc_init
->nsc_ircc_open
self = netdev_priv(dev)
register_netdev(dev)
nsc_ircc_net_ioctl
->nsc_ircc_change_speed
self->dongle_id = ... <READ self->io.dongle_id>
(nsc-ircc.c: line 485) (nsc-ircc.c: line 1318)
platform_device_register_simple
Before the initialization of self->dongle_id in msc_ircc_open() its
value is 0. Thus if read access to its value in nsc_ircc_change_speed
occurs before the initialization there will be an attempt to change
speed of dongle with undesired id (if the dongle with id 0 exists). Is
this case feasible from your point of view?
Thank you for your time.
-- Anton Volkov
Linux Verification Center, ISPRAS
web: http://linuxtesting.org
e-mail: avolkov@ispras.ru
^ permalink raw reply
* Re: [PATCH net-next 0/4] net: mvpp2: fix the mac address retrieval logic
From: Antoine Tenart @ 2017-08-25 13:58 UTC (permalink / raw)
To: David Miller
Cc: antoine.tenart, thomas.petazzoni, andrew, gregory.clement, nadavh,
linux, linux-kernel, mw, stefanc, netdev
In-Reply-To: <20170824.214624.250495333472785242.davem@davemloft.net>
[-- Attachment #1: Type: text/plain, Size: 1529 bytes --]
Hi Dave,
On Thu, Aug 24, 2017 at 09:46:24PM -0700, David Miller wrote:
> From: Antoine Tenart <antoine.tenart@free-electrons.com>
> Date: Thu, 24 Aug 2017 11:46:54 +0200
>
> > The MAC address retrieval logic was broken and when using the PPv2
> > driver on PPv2.2 engines I ended up using the same mac address on all
> > ports. This series of patches fixes this, and also tackle a possible bug
> > when defining the mac address in the device tree.
> >
> > To fix this in a nice way I ended up using a dedicated function to
> > handle the mac retrieval logic. This can be hard to backport into stable
> > kernels. This is why I also made a quick fix which is easy to backport
> > (patch 1/14), to tackle down the PPv2.2 mac retrieval bug. Let me know
> > if this approach is the proper way to handle this or if I should do
> > something else.
>
> This patch series doesn't apply to any of my trees, that is the first
> thing.
That is very strange, my patches were based on top of net-next. I'll
double check if they apply correctly before sending the v2.
> Secondly, this is a bug fix, and the bug exists in the 'net' tree.
> Therefore this patch series should target the 'net' tree.
OK, that's the question I was asking. I'll resent everything to net
then.
> Please always target legitimate bug fixes at the 'net' tree, rather
> than 'net-next'.
Sure, will do.
Thanks!
Antoine
--
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH] staging: rtlwifi: Improve debugging by using debugfs
From: Larry Finger @ 2017-08-25 13:47 UTC (permalink / raw)
To: Andrew Lunn
Cc: gregkh, netdev, devel, Ping-Ke Shih, Yan-Hsuan Chuang,
Birming Chiu, Shaofu, Steven Ting
In-Reply-To: <20170825015421.GA8852@lunn.ch>
On 08/24/2017 08:54 PM, Andrew Lunn wrote:
> netdev frowns upon debugfs. You should try to keep this altogether,
> making it easy to throw away before the driver is moved out of
> staging.
>
> You might want to look at ethtool -d. That will be accepted.
Andrew,
What is the problem with debugfs?
Please suggest which driver has the best example of an ethtool -d implementation
that we might study.
The first version of the debugfs changes were sent to wireless-drivers on July
2. Why are we first hearing of this objection nearly 2 months later?
Larry
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox