blob: b072a84fbe1c78993a971bfdea94383c1708e7a7 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001#ifndef __LINUX_MROUTE_H
2#define __LINUX_MROUTE_H
3
Linus Torvalds1da177e2005-04-16 15:20:36 -07004#include <linux/in.h>
David S. Miller7c19a3d2008-08-29 14:37:23 -07005#include <linux/pim.h>
Nikolay Aleksandrov8fb472c2017-01-12 15:53:33 +01006#include <linux/rhashtable.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007#include <net/sock.h>
Yotam Gigi478e4c22017-09-27 08:23:16 +02008#include <net/fib_rules.h>
Yotam Gigi4d65b942017-09-27 08:23:13 +02009#include <net/fib_notifier.h>
David Howells607ca462012-10-13 10:46:48 +010010#include <uapi/linux/mroute.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011
Pavel Emelyanov6a9fb942007-11-05 21:32:31 -080012#ifdef CONFIG_IP_MROUTE
13static inline int ip_mroute_opt(int opt)
14{
Nikolay Aleksandrov520191b2015-11-26 15:23:46 +010015 return opt >= MRT_BASE && opt <= MRT_MAX;
Pavel Emelyanov6a9fb942007-11-05 21:32:31 -080016}
Pavel Emelyanov6a9fb942007-11-05 21:32:31 -080017
Nikolay Aleksandrov520191b2015-11-26 15:23:46 +010018int ip_mroute_setsockopt(struct sock *, int, char __user *, unsigned int);
19int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
20int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
21int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
22int ip_mr_init(void);
Yotam Gigi478e4c22017-09-27 08:23:16 +020023bool ipmr_rule_default(const struct fib_rule *rule);
YOSHIFUJI Hideakie0835f82008-07-03 16:51:22 +090024#else
Nikolay Aleksandrov520191b2015-11-26 15:23:46 +010025static inline int ip_mroute_setsockopt(struct sock *sock, int optname,
26 char __user *optval, unsigned int optlen)
YOSHIFUJI Hideakie0835f82008-07-03 16:51:22 +090027{
28 return -ENOPROTOOPT;
29}
30
Nikolay Aleksandrov520191b2015-11-26 15:23:46 +010031static inline int ip_mroute_getsockopt(struct sock *sock, int optname,
32 char __user *optval, int __user *optlen)
YOSHIFUJI Hideakie0835f82008-07-03 16:51:22 +090033{
34 return -ENOPROTOOPT;
35}
36
Nikolay Aleksandrov520191b2015-11-26 15:23:46 +010037static inline int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
YOSHIFUJI Hideakie0835f82008-07-03 16:51:22 +090038{
39 return -ENOIOCTLCMD;
40}
41
42static inline int ip_mr_init(void)
43{
44 return 0;
45}
Nikolay Aleksandrov520191b2015-11-26 15:23:46 +010046
47static inline int ip_mroute_opt(int opt)
48{
49 return 0;
50}
Yotam Gigi478e4c22017-09-27 08:23:16 +020051
52static inline bool ipmr_rule_default(const struct fib_rule *rule)
53{
54 return true;
55}
YOSHIFUJI Hideakie0835f82008-07-03 16:51:22 +090056#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Eric Dumazetd94d9fe2009-11-04 09:50:58 -080058struct vif_device {
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 struct net_device *dev; /* Device we are using */
60 unsigned long bytes_in,bytes_out;
61 unsigned long pkt_in,pkt_out; /* Statistics */
62 unsigned long rate_limit; /* Traffic shaping (NI) */
63 unsigned char threshold; /* TTL threshold */
64 unsigned short flags; /* Control flags */
Al Viro114c7842006-09-27 18:39:29 -070065 __be32 local,remote; /* Addresses(remote for tunnels)*/
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 int link; /* Physical interface index */
67};
68
Yotam Gigi4d65b942017-09-27 08:23:13 +020069struct vif_entry_notifier_info {
70 struct fib_notifier_info info;
71 struct net_device *dev;
72 vifi_t vif_index;
73 unsigned short vif_flags;
74 u32 tb_id;
75};
76
Linus Torvalds1da177e2005-04-16 15:20:36 -070077#define VIFF_STATIC 0x8000
78
Nikolay Aleksandrov5ea1f132015-11-26 15:23:47 +010079#define VIF_EXISTS(_mrt, _idx) ((_mrt)->vif_table[_idx].dev != NULL)
Nikolay Aleksandrov5ea1f132015-11-26 15:23:47 +010080
81struct mr_table {
82 struct list_head list;
83 possible_net_t net;
84 u32 id;
85 struct sock __rcu *mroute_sk;
86 struct timer_list ipmr_expire_timer;
87 struct list_head mfc_unres_queue;
Nikolay Aleksandrov5ea1f132015-11-26 15:23:47 +010088 struct vif_device vif_table[MAXVIFS];
Nikolay Aleksandrov8fb472c2017-01-12 15:53:33 +010089 struct rhltable mfc_hash;
90 struct list_head mfc_cache_list;
Nikolay Aleksandrov5ea1f132015-11-26 15:23:47 +010091 int maxvif;
92 atomic_t cache_resolve_queue_len;
93 bool mroute_do_assert;
94 bool mroute_do_pim;
95 int mroute_reg_vif_num;
96};
97
Nikolay Aleksandrov06bd6c02015-11-26 15:23:45 +010098/* mfc_flags:
99 * MFC_STATIC - the entry was added statically (not by a routing daemon)
Yotam Gigic7c0bbe2017-09-27 08:23:15 +0200100 * MFC_OFFLOAD - the entry was offloaded to the hardware
Nikolay Aleksandrov06bd6c02015-11-26 15:23:45 +0100101 */
102enum {
103 MFC_STATIC = BIT(0),
Yotam Gigic7c0bbe2017-09-27 08:23:15 +0200104 MFC_OFFLOAD = BIT(1),
Nikolay Aleksandrov06bd6c02015-11-26 15:23:45 +0100105};
106
Nikolay Aleksandrov8fb472c2017-01-12 15:53:33 +0100107struct mfc_cache_cmp_arg {
108 __be32 mfc_mcastgrp;
109 __be32 mfc_origin;
110};
111
112/**
113 * struct mfc_cache - multicast routing entries
114 * @mnode: rhashtable list
115 * @mfc_mcastgrp: destination multicast group address
116 * @mfc_origin: source address
117 * @cmparg: used for rhashtable comparisons
118 * @mfc_parent: source interface (iif)
119 * @mfc_flags: entry flags
120 * @expires: unresolved entry expire time
121 * @unresolved: unresolved cached skbs
122 * @last_assert: time of last assert
123 * @minvif: minimum VIF id
124 * @maxvif: maximum VIF id
125 * @bytes: bytes that have passed for this entry
126 * @pkt: packets that have passed for this entry
127 * @wrong_if: number of wrong source interface hits
128 * @lastuse: time of last use of the group (traffic or update)
129 * @ttls: OIF TTL threshold array
Yotam Gigi310ebbb2017-09-27 08:23:12 +0200130 * @refcount: reference count for this entry
Nikolay Aleksandrov8fb472c2017-01-12 15:53:33 +0100131 * @list: global entry list
132 * @rcu: used for entry destruction
133 */
Eric Dumazetd94d9fe2009-11-04 09:50:58 -0800134struct mfc_cache {
Nikolay Aleksandrov8fb472c2017-01-12 15:53:33 +0100135 struct rhlist_head mnode;
136 union {
137 struct {
138 __be32 mfc_mcastgrp;
139 __be32 mfc_origin;
140 };
141 struct mfc_cache_cmp_arg cmparg;
142 };
143 vifi_t mfc_parent;
144 int mfc_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
146 union {
147 struct {
148 unsigned long expires;
Nikolay Aleksandrov8fb472c2017-01-12 15:53:33 +0100149 struct sk_buff_head unresolved;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 } unres;
151 struct {
152 unsigned long last_assert;
153 int minvif;
154 int maxvif;
155 unsigned long bytes;
156 unsigned long pkt;
157 unsigned long wrong_if;
Nikolay Aleksandrov43b9e122016-07-14 19:28:27 +0300158 unsigned long lastuse;
Nikolay Aleksandrov8fb472c2017-01-12 15:53:33 +0100159 unsigned char ttls[MAXVIFS];
Yotam Gigi310ebbb2017-09-27 08:23:12 +0200160 refcount_t refcount;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 } res;
162 } mfc_un;
Nikolay Aleksandrov8fb472c2017-01-12 15:53:33 +0100163 struct list_head list;
Eric Dumazeta8c94862010-10-01 16:15:08 +0000164 struct rcu_head rcu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165};
166
Yotam Gigi4d65b942017-09-27 08:23:13 +0200167struct mfc_entry_notifier_info {
168 struct fib_notifier_info info;
169 struct mfc_cache *mfc;
170 u32 tb_id;
171};
172
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173struct rtmsg;
Nikolay Aleksandrov520191b2015-11-26 15:23:46 +0100174int ipmr_get_route(struct net *net, struct sk_buff *skb,
175 __be32 saddr, __be32 daddr,
David Ahern9f09eae2017-01-06 17:39:06 -0800176 struct rtmsg *rtm, u32 portid);
Yotam Gigi310ebbb2017-09-27 08:23:12 +0200177
178#ifdef CONFIG_IP_MROUTE
179void ipmr_cache_free(struct mfc_cache *mfc_cache);
180#else
181static inline void ipmr_cache_free(struct mfc_cache *mfc_cache)
182{
183}
184#endif
185
186static inline void ipmr_cache_put(struct mfc_cache *c)
187{
188 if (refcount_dec_and_test(&c->mfc_un.res.refcount))
189 ipmr_cache_free(c);
190}
191static inline void ipmr_cache_hold(struct mfc_cache *c)
192{
193 refcount_inc(&c->mfc_un.res.refcount);
194}
195
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196#endif