linux/include/net/lwtunnel.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __NET_LWTUNNEL_H
   3#define __NET_LWTUNNEL_H 1
   4
   5#include <linux/lwtunnel.h>
   6#include <linux/netdevice.h>
   7#include <linux/skbuff.h>
   8#include <linux/types.h>
   9#include <net/route.h>
  10
  11#include <linux/rh_kabi.h>
  12
  13#define LWTUNNEL_HASH_BITS   7
  14#define LWTUNNEL_HASH_SIZE   (1 << LWTUNNEL_HASH_BITS)
  15
  16/* lw tunnel state flags */
  17#define LWTUNNEL_STATE_OUTPUT_REDIRECT  BIT(0)
  18#define LWTUNNEL_STATE_INPUT_REDIRECT   BIT(1)
  19#define LWTUNNEL_STATE_XMIT_REDIRECT    BIT(2)
  20
  21enum {
  22        LWTUNNEL_XMIT_DONE,
  23        LWTUNNEL_XMIT_CONTINUE,
  24};
  25
  26
  27struct lwtunnel_state {
  28        __u16           type;
  29        __u16           flags;
  30        __u16           headroom;
  31        atomic_t        refcnt;
  32        int             (*orig_output)(struct net *net, struct sock *sk, struct sk_buff *skb);
  33        int             (*orig_input)(struct sk_buff *);
  34        struct          rcu_head rcu;
  35
  36        RH_KABI_RESERVE(1)
  37        RH_KABI_RESERVE(2)
  38        RH_KABI_RESERVE(3)
  39        RH_KABI_RESERVE(4)
  40        __u8            data[0];
  41};
  42
  43struct lwtunnel_encap_ops {
  44        int (*build_state)(struct nlattr *encap,
  45                           unsigned int family, const void *cfg,
  46                           struct lwtunnel_state **ts,
  47                           struct netlink_ext_ack *extack);
  48        void (*destroy_state)(struct lwtunnel_state *lws);
  49        int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
  50        int (*input)(struct sk_buff *skb);
  51        int (*fill_encap)(struct sk_buff *skb,
  52                          struct lwtunnel_state *lwtstate);
  53        int (*get_encap_size)(struct lwtunnel_state *lwtstate);
  54        int (*cmp_encap)(struct lwtunnel_state *a, struct lwtunnel_state *b);
  55        int (*xmit)(struct sk_buff *skb);
  56
  57        struct module *owner;
  58};
  59
  60#ifdef CONFIG_LWTUNNEL
  61void lwtstate_free(struct lwtunnel_state *lws);
  62
  63static inline struct lwtunnel_state *
  64lwtstate_get(struct lwtunnel_state *lws)
  65{
  66        if (lws)
  67                atomic_inc(&lws->refcnt);
  68
  69        return lws;
  70}
  71
  72static inline void lwtstate_put(struct lwtunnel_state *lws)
  73{
  74        if (!lws)
  75                return;
  76
  77        if (atomic_dec_and_test(&lws->refcnt))
  78                lwtstate_free(lws);
  79}
  80
  81static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
  82{
  83        if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_OUTPUT_REDIRECT))
  84                return true;
  85
  86        return false;
  87}
  88
  89static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate)
  90{
  91        if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_INPUT_REDIRECT))
  92                return true;
  93
  94        return false;
  95}
  96
  97static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
  98{
  99        if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_XMIT_REDIRECT))
 100                return true;
 101
 102        return false;
 103}
 104
 105static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
 106                                             unsigned int mtu)
 107{
 108        if ((lwtunnel_xmit_redirect(lwtstate) ||
 109             lwtunnel_output_redirect(lwtstate)) && lwtstate->headroom < mtu)
 110                return lwtstate->headroom;
 111
 112        return 0;
 113}
 114
 115int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
 116                           unsigned int num);
 117int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
 118                           unsigned int num);
 119int lwtunnel_valid_encap_type(u16 encap_type,
 120                              struct netlink_ext_ack *extack);
 121int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
 122                                   struct netlink_ext_ack *extack);
 123int lwtunnel_build_state(u16 encap_type,
 124                         struct nlattr *encap,
 125                         unsigned int family, const void *cfg,
 126                         struct lwtunnel_state **lws,
 127                         struct netlink_ext_ack *extack);
 128int lwtunnel_fill_encap(struct sk_buff *skb,
 129                        struct lwtunnel_state *lwtstate);
 130int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate);
 131struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len);
 132int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b);
 133int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb);
 134int lwtunnel_input(struct sk_buff *skb);
 135int lwtunnel_xmit(struct sk_buff *skb);
 136int bpf_lwt_push_ip_encap(struct sk_buff *skb, void *hdr, u32 len,
 137                          bool ingress);
 138
 139static inline void lwtunnel_set_redirect(struct dst_entry *dst)
 140{
 141        if (lwtunnel_output_redirect(dst->lwtstate)) {
 142                dst->lwtstate->orig_output = dst->output;
 143                dst->output = lwtunnel_output;
 144        }
 145        if (lwtunnel_input_redirect(dst->lwtstate)) {
 146                dst->lwtstate->orig_input = dst->input;
 147                dst->input = lwtunnel_input;
 148        }
 149}
 150#else
 151
 152static inline void lwtstate_free(struct lwtunnel_state *lws)
 153{
 154}
 155
 156static inline struct lwtunnel_state *
 157lwtstate_get(struct lwtunnel_state *lws)
 158{
 159        return lws;
 160}
 161
 162static inline void lwtstate_put(struct lwtunnel_state *lws)
 163{
 164}
 165
 166static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
 167{
 168        return false;
 169}
 170
 171static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate)
 172{
 173        return false;
 174}
 175
 176static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
 177{
 178        return false;
 179}
 180
 181static inline void lwtunnel_set_redirect(struct dst_entry *dst)
 182{
 183}
 184
 185static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
 186                                             unsigned int mtu)
 187{
 188        return 0;
 189}
 190
 191static inline int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
 192                                         unsigned int num)
 193{
 194        return -EOPNOTSUPP;
 195
 196}
 197
 198static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
 199                                         unsigned int num)
 200{
 201        return -EOPNOTSUPP;
 202}
 203
 204static inline int lwtunnel_valid_encap_type(u16 encap_type,
 205                                            struct netlink_ext_ack *extack)
 206{
 207        NL_SET_ERR_MSG(extack, "CONFIG_LWTUNNEL is not enabled in this kernel");
 208        return -EOPNOTSUPP;
 209}
 210static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
 211                                                 struct netlink_ext_ack *extack)
 212{
 213        /* return 0 since we are not walking attr looking for
 214         * RTA_ENCAP_TYPE attribute on nexthops.
 215         */
 216        return 0;
 217}
 218
 219static inline int lwtunnel_build_state(u16 encap_type,
 220                                       struct nlattr *encap,
 221                                       unsigned int family, const void *cfg,
 222                                       struct lwtunnel_state **lws,
 223                                       struct netlink_ext_ack *extack)
 224{
 225        return -EOPNOTSUPP;
 226}
 227
 228static inline int lwtunnel_fill_encap(struct sk_buff *skb,
 229                                      struct lwtunnel_state *lwtstate)
 230{
 231        return 0;
 232}
 233
 234static inline int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate)
 235{
 236        return 0;
 237}
 238
 239static inline struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len)
 240{
 241        return NULL;
 242}
 243
 244static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a,
 245                                     struct lwtunnel_state *b)
 246{
 247        return 0;
 248}
 249
 250static inline int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 251{
 252        return -EOPNOTSUPP;
 253}
 254
 255static inline int lwtunnel_input(struct sk_buff *skb)
 256{
 257        return -EOPNOTSUPP;
 258}
 259
 260static inline int lwtunnel_xmit(struct sk_buff *skb)
 261{
 262        return -EOPNOTSUPP;
 263}
 264
 265#endif /* CONFIG_LWTUNNEL */
 266
 267#define MODULE_ALIAS_RTNL_LWT(encap_type) MODULE_ALIAS("rtnl-lwt-" __stringify(encap_type))
 268
 269#endif /* __NET_LWTUNNEL_H */
 270