mpls: multipath route support
[firefly-linux-kernel-4.4.55.git] / net / mpls / internal.h
index 2681a4ba6c375f3faf83498150350ddea7392ccc..d7757be39877e84530ebecfc18fbb7dab502f979 100644 (file)
@@ -21,6 +21,54 @@ struct mpls_dev {
 
 struct sk_buff;
 
+#define LABEL_NOT_SPECIFIED (1 << 20)
+#define MAX_NEW_LABELS 2
+
+/* This maximum ha length copied from the definition of struct neighbour */
+#define MAX_VIA_ALEN (ALIGN(MAX_ADDR_LEN, sizeof(unsigned long)))
+
+enum mpls_payload_type {
+       MPT_UNSPEC, /* IPv4 or IPv6 */
+       MPT_IPV4 = 4,
+       MPT_IPV6 = 6,
+
+       /* Other types not implemented:
+        *  - Pseudo-wire with or without control word (RFC4385)
+        *  - GAL (RFC5586)
+        */
+};
+
+struct mpls_nh { /* next hop label forwarding entry */
+       struct net_device __rcu *nh_dev;
+       u32                     nh_label[MAX_NEW_LABELS];
+       u8                      nh_labels;
+       u8                      nh_via_alen;
+       u8                      nh_via_table;
+       u8                      nh_via[MAX_VIA_ALEN];
+};
+
+struct mpls_route { /* next hop label forwarding entry */
+       struct rcu_head         rt_rcu;
+       u8                      rt_protocol;
+       u8                      rt_payload_type;
+       int                     rt_nhn;
+       struct mpls_nh          rt_nh[0];
+};
+
+#define for_nexthops(rt) {                                             \
+       int nhsel; struct mpls_nh *nh;                  \
+       for (nhsel = 0, nh = (rt)->rt_nh;                               \
+            nhsel < (rt)->rt_nhn;                                      \
+            nh++, nhsel++)
+
+#define change_nexthops(rt) {                                          \
+       int nhsel; struct mpls_nh *nh;                          \
+       for (nhsel = 0, nh = (struct mpls_nh *)((rt)->rt_nh);   \
+            nhsel < (rt)->rt_nhn;                                      \
+            nh++, nhsel++)
+
+#define endfor_nexthops(rt) }
+
 static inline struct mpls_shim_hdr *mpls_hdr(const struct sk_buff *skb)
 {
        return (struct mpls_shim_hdr *)skb_network_header(skb);
@@ -52,8 +100,10 @@ static inline struct mpls_entry_decoded mpls_entry_decode(struct mpls_shim_hdr *
 
 int nla_put_labels(struct sk_buff *skb, int attrtype,  u8 labels,
                   const u32 label[]);
-int nla_get_labels(const struct nlattr *nla, u32 max_labels, u32 *labels,
+int nla_get_labels(const struct nlattr *nla, u32 max_labels, u8 *labels,
                   u32 label[]);
+int nla_get_via(const struct nlattr *nla, u8 *via_alen, u8 *via_table,
+               u8 via[]);
 bool mpls_output_possible(const struct net_device *dev);
 unsigned int mpls_dev_mtu(const struct net_device *dev);
 bool mpls_pkt_too_big(const struct sk_buff *skb, unsigned int mtu);