[PATCH net-next 03/22] ipv4: support for fib route lwtunnel encap attributes

2015-07-21 Thread Thomas Graf
From: Roopa Prabhu ro...@cumulusnetworks.com

This patch adds support in ipv4 fib functions to parse user
provided encap attributes and attach encap state data to fib_nh
and rtable.

Signed-off-by: Roopa Prabhu ro...@cumulusnetworks.com
---
 include/net/ip_fib.h |  5 ++-
 include/net/route.h  |  1 +
 net/ipv4/fib_frontend.c  |  8 
 net/ipv4/fib_semantics.c | 96 +++-
 net/ipv4/route.c | 16 +++-
 5 files changed, 122 insertions(+), 4 deletions(-)

diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 49c142b..5e01960 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -44,7 +44,9 @@ struct fib_config {
u32 fc_flow;
u32 fc_nlflags;
struct nl_info  fc_nlinfo;
- };
+   struct nlattr   *fc_encap;
+   u16 fc_encap_type;
+};
 
 struct fib_info;
 struct rtable;
@@ -89,6 +91,7 @@ struct fib_nh {
struct rtable __rcu * __percpu *nh_pcpu_rth_output;
struct rtable __rcu *nh_rth_input;
struct fnhe_hash_bucket __rcu *nh_exceptions;
+   struct lwtunnel_state   *nh_lwtstate;
 };
 
 /*
diff --git a/include/net/route.h b/include/net/route.h
index fe22d03..2d45f41 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -66,6 +66,7 @@ struct rtable {
 
struct list_headrt_uncached;
struct uncached_list*rt_uncached_list;
+   struct lwtunnel_state   *rt_lwtstate;
 };
 
 static inline bool rt_is_input_route(const struct rtable *rt)
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 6bbc549..9b2019c 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -591,6 +591,8 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX + 1] = {
[RTA_METRICS]   = { .type = NLA_NESTED },
[RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
[RTA_FLOW]  = { .type = NLA_U32 },
+   [RTA_ENCAP_TYPE]= { .type = NLA_U16 },
+   [RTA_ENCAP] = { .type = NLA_NESTED },
 };
 
 static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
@@ -656,6 +658,12 @@ static int rtm_to_fib_config(struct net *net, struct 
sk_buff *skb,
case RTA_TABLE:
cfg-fc_table = nla_get_u32(attr);
break;
+   case RTA_ENCAP:
+   cfg-fc_encap = attr;
+   break;
+   case RTA_ENCAP_TYPE:
+   cfg-fc_encap_type = nla_get_u16(attr);
+   break;
}
}
 
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index c7358ea..6754c64 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -42,6 +42,7 @@
 #include net/ip_fib.h
 #include net/netlink.h
 #include net/nexthop.h
+#include net/lwtunnel.h
 
 #include fib_lookup.h
 
@@ -208,6 +209,7 @@ static void free_fib_info_rcu(struct rcu_head *head)
change_nexthops(fi) {
if (nexthop_nh-nh_dev)
dev_put(nexthop_nh-nh_dev);
+   lwtunnel_state_put(nexthop_nh-nh_lwtstate);
free_nh_exceptions(nexthop_nh);
rt_fibinfo_free_cpus(nexthop_nh-nh_pcpu_rth_output);
rt_fibinfo_free(nexthop_nh-nh_rth_input);
@@ -266,6 +268,7 @@ static inline int nh_comp(const struct fib_info *fi, const 
struct fib_info *ofi)
 #ifdef CONFIG_IP_ROUTE_CLASSID
nh-nh_tclassid != onh-nh_tclassid ||
 #endif
+   lwtunnel_cmp_encap(nh-nh_lwtstate, onh-nh_lwtstate) ||
((nh-nh_flags ^ onh-nh_flags)  ~RTNH_COMPARE_MASK))
return -1;
onh++;
@@ -366,6 +369,7 @@ static inline size_t fib_nlmsg_size(struct fib_info *fi)
payload += nla_total_size((RTAX_MAX * nla_total_size(4)));
 
if (fi-fib_nhs) {
+   size_t nh_encapsize = 0;
/* Also handles the special case fib_nhs == 1 */
 
/* each nexthop is packed in an attribute */
@@ -374,8 +378,21 @@ static inline size_t fib_nlmsg_size(struct fib_info *fi)
/* may contain flow and gateway attribute */
nhsize += 2 * nla_total_size(4);
 
+   /* grab encap info */
+   for_nexthops(fi) {
+   if (nh-nh_lwtstate) {
+   /* RTA_ENCAP_TYPE */
+   nh_encapsize += lwtunnel_get_encap_size(
+   nh-nh_lwtstate);
+   /* RTA_ENCAP */
+   nh_encapsize +=  nla_total_size(2);
+   }
+   } endfor_nexthops(fi);
+
/* all nexthops are packed in a nested attribute */
-   payload += nla_total_size(fi-fib_nhs * nhsize);
+   payload += 

[PATCH net-next 03/22] ipv4: support for fib route lwtunnel encap attributes

2015-07-17 Thread Thomas Graf
From: Roopa Prabhu ro...@cumulusnetworks.com

This patch adds support in ipv4 fib functions to parse user
provided encap attributes and attach encap state data to fib_nh
and rtable.

Signed-off-by: Roopa Prabhu ro...@cumulusnetworks.com
---
 include/net/ip_fib.h |  5 ++-
 include/net/route.h  |  1 +
 net/ipv4/fib_frontend.c  |  8 
 net/ipv4/fib_semantics.c | 96 +++-
 net/ipv4/route.c | 16 +++-
 5 files changed, 122 insertions(+), 4 deletions(-)

diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 49c142b..5e01960 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -44,7 +44,9 @@ struct fib_config {
u32 fc_flow;
u32 fc_nlflags;
struct nl_info  fc_nlinfo;
- };
+   struct nlattr   *fc_encap;
+   u16 fc_encap_type;
+};
 
 struct fib_info;
 struct rtable;
@@ -89,6 +91,7 @@ struct fib_nh {
struct rtable __rcu * __percpu *nh_pcpu_rth_output;
struct rtable __rcu *nh_rth_input;
struct fnhe_hash_bucket __rcu *nh_exceptions;
+   struct lwtunnel_state   *nh_lwtstate;
 };
 
 /*
diff --git a/include/net/route.h b/include/net/route.h
index fe22d03..2d45f41 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -66,6 +66,7 @@ struct rtable {
 
struct list_headrt_uncached;
struct uncached_list*rt_uncached_list;
+   struct lwtunnel_state   *rt_lwtstate;
 };
 
 static inline bool rt_is_input_route(const struct rtable *rt)
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 6bbc549..9b2019c 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -591,6 +591,8 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX + 1] = {
[RTA_METRICS]   = { .type = NLA_NESTED },
[RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
[RTA_FLOW]  = { .type = NLA_U32 },
+   [RTA_ENCAP_TYPE]= { .type = NLA_U16 },
+   [RTA_ENCAP] = { .type = NLA_NESTED },
 };
 
 static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
@@ -656,6 +658,12 @@ static int rtm_to_fib_config(struct net *net, struct 
sk_buff *skb,
case RTA_TABLE:
cfg-fc_table = nla_get_u32(attr);
break;
+   case RTA_ENCAP:
+   cfg-fc_encap = attr;
+   break;
+   case RTA_ENCAP_TYPE:
+   cfg-fc_encap_type = nla_get_u16(attr);
+   break;
}
}
 
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index c7358ea..6754c64 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -42,6 +42,7 @@
 #include net/ip_fib.h
 #include net/netlink.h
 #include net/nexthop.h
+#include net/lwtunnel.h
 
 #include fib_lookup.h
 
@@ -208,6 +209,7 @@ static void free_fib_info_rcu(struct rcu_head *head)
change_nexthops(fi) {
if (nexthop_nh-nh_dev)
dev_put(nexthop_nh-nh_dev);
+   lwtunnel_state_put(nexthop_nh-nh_lwtstate);
free_nh_exceptions(nexthop_nh);
rt_fibinfo_free_cpus(nexthop_nh-nh_pcpu_rth_output);
rt_fibinfo_free(nexthop_nh-nh_rth_input);
@@ -266,6 +268,7 @@ static inline int nh_comp(const struct fib_info *fi, const 
struct fib_info *ofi)
 #ifdef CONFIG_IP_ROUTE_CLASSID
nh-nh_tclassid != onh-nh_tclassid ||
 #endif
+   lwtunnel_cmp_encap(nh-nh_lwtstate, onh-nh_lwtstate) ||
((nh-nh_flags ^ onh-nh_flags)  ~RTNH_COMPARE_MASK))
return -1;
onh++;
@@ -366,6 +369,7 @@ static inline size_t fib_nlmsg_size(struct fib_info *fi)
payload += nla_total_size((RTAX_MAX * nla_total_size(4)));
 
if (fi-fib_nhs) {
+   size_t nh_encapsize = 0;
/* Also handles the special case fib_nhs == 1 */
 
/* each nexthop is packed in an attribute */
@@ -374,8 +378,21 @@ static inline size_t fib_nlmsg_size(struct fib_info *fi)
/* may contain flow and gateway attribute */
nhsize += 2 * nla_total_size(4);
 
+   /* grab encap info */
+   for_nexthops(fi) {
+   if (nh-nh_lwtstate) {
+   /* RTA_ENCAP_TYPE */
+   nh_encapsize += lwtunnel_get_encap_size(
+   nh-nh_lwtstate);
+   /* RTA_ENCAP */
+   nh_encapsize +=  nla_total_size(2);
+   }
+   } endfor_nexthops(fi);
+
/* all nexthops are packed in a nested attribute */
-   payload += nla_total_size(fi-fib_nhs * nhsize);
+   payload +=