1#ifndef __LINUX_MROUTE6_H
2#define __LINUX_MROUTE6_H
3
4#include <linux/sockios.h>
5
6/*
7 *	Based on the MROUTING 3.5 defines primarily to keep
8 *	source compatibility with BSD.
9 *
10 *	See the pim6sd code for the original history.
11 *
12 *      Protocol Independent Multicast (PIM) data structures included
13 *      Carlos Picoto (cap@di.fc.ul.pt)
14 *
15 */
16
17#define MRT6_BASE	200
18#define MRT6_INIT	(MRT6_BASE)	/* Activate the kernel mroute code 	*/
19#define MRT6_DONE	(MRT6_BASE+1)	/* Shutdown the kernel mroute		*/
20#define MRT6_ADD_MIF	(MRT6_BASE+2)	/* Add a virtual interface		*/
21#define MRT6_DEL_MIF	(MRT6_BASE+3)	/* Delete a virtual interface		*/
22#define MRT6_ADD_MFC	(MRT6_BASE+4)	/* Add a multicast forwarding entry	*/
23#define MRT6_DEL_MFC	(MRT6_BASE+5)	/* Delete a multicast forwarding entry	*/
24#define MRT6_VERSION	(MRT6_BASE+6)	/* Get the kernel multicast version	*/
25#define MRT6_ASSERT	(MRT6_BASE+7)	/* Activate PIM assert mode		*/
26#define MRT6_PIM	(MRT6_BASE+8)	/* enable PIM code	*/
27
28#define SIOCGETMIFCNT_IN6	SIOCPROTOPRIVATE	/* IP protocol privates */
29#define SIOCGETSGCNT_IN6	(SIOCPROTOPRIVATE+1)
30#define SIOCGETRPF	(SIOCPROTOPRIVATE+2)
31
32#define MAXMIFS		32
33typedef unsigned long mifbitmap_t;	/* User mode code depends on this lot */
34typedef unsigned short mifi_t;
35#define ALL_MIFS	((mifi_t)(-1))
36
37#ifndef IF_SETSIZE
38#define IF_SETSIZE      256
39#endif
40
41typedef u_int32_t       if_mask;
42#define NIFBITS (sizeof(if_mask) * 8)        /* bits per mask */
43
44#ifndef howmany
45#define howmany(x, y)   (((x) + ((y) - 1)) / (y))
46#endif
47
48typedef struct if_set {
49	        if_mask ifs_bits[howmany(IF_SETSIZE, NIFBITS)];
50} if_set;
51
52#define IF_SET(n, p)    ((p)->ifs_bits[(n)/NIFBITS] |= (1 << ((n) % NIFBITS)))
53#define IF_CLR(n, p)    ((p)->ifs_bits[(n)/NIFBITS] &= ~(1 << ((n) % NIFBITS)))
54#define IF_ISSET(n, p)  ((p)->ifs_bits[(n)/NIFBITS] & (1 << ((n) % NIFBITS)))
55#define IF_COPY(f, t)   bcopy(f, t, sizeof(*(f)))
56#define IF_ZERO(p)      bzero(p, sizeof(*(p)))
57
58/*
59 	Same idea as select
60
61#define VIFM_SET(n,m)	((m)|=(1<<(n)))
62#define VIFM_CLR(n,m)	((m)&=~(1<<(n)))
63#define VIFM_ISSET(n,m)	((m)&(1<<(n)))
64#define VIFM_CLRALL(m)	((m)=0)
65#define VIFM_COPY(mfrom,mto)	((mto)=(mfrom))
66#define VIFM_SAME(m1,m2)	((m1)==(m2))
67*/
68
69/*
70 *	Passed by mrouted for an MRT_ADD_MIF - again we use the
71 *	mrouted 3.6 structures for compatibility
72 */
73
74struct mif6ctl {
75	mifi_t	mif6c_mifi;		/* Index of MIF */
76	unsigned char mif6c_flags;	/* MIFF_ flags */
77	unsigned char vifc_threshold;	/* ttl limit */
78	unsigned int vifc_rate_limit;	/* Rate limiter values (NI) */
79	u_short	 mif6c_pifi;		/* the index of the physical IF */
80};
81
82#define MIFF_REGISTER	0x1	/* register vif	*/
83
84/*
85 *	Cache manipulation structures for mrouted and PIMd
86 */
87
88struct mf6cctl
89{
90	struct sockaddr_in6 mf6cc_origin;		/* Origin of mcast	*/
91	struct sockaddr_in6 mf6cc_mcastgrp;		/* Group in question	*/
92	mifi_t	mf6cc_parent;			/* Where it arrived	*/
93	struct if_set mf6cc_ifset;		/* Where it is going */
94	unsigned int mfcc_pkt_cnt;		/* pkt count for src-grp */
95	unsigned int mfcc_byte_cnt;
96	unsigned int mfcc_wrong_if;
97	int	     mfcc_expire;
98};
99
100/*
101 *	Group count retrieval for pim6sd
102 */
103
104struct sioc_sg_req6
105{
106	struct sockaddr_in6 src;
107	struct sockaddr_in6 grp;
108	unsigned long pktcnt;
109	unsigned long bytecnt;
110	unsigned long wrong_if;
111};
112
113/*
114 *	To get vif packet counts
115 */
116
117struct sioc_mif_req6
118{
119	mifi_t	mifi;		/* Which iface */
120	unsigned long icount;	/* In packets */
121	unsigned long ocount;	/* Out packets */
122	unsigned long ibytes;	/* In bytes */
123	unsigned long obytes;	/* Out bytes */
124};
125
126/*
127 *	That's all usermode folks
128 */
129
130#ifdef __KERNEL__
131struct inet6_dev * ipv6_find_idev(struct net_device *dev);
132#include <net/sock.h>
133
134extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, int);
135extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
136extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg);
137extern void ip6_mr_init(void);
138
139struct mif_device
140{
141	struct net_device 	*dev;			/* Device we are using */
142	unsigned long	bytes_in,bytes_out;
143	unsigned long	pkt_in,pkt_out;		/* Statistics 			*/
144	unsigned long	rate_limit;		/* Traffic shaping (NI) 	*/
145	unsigned char	threshold;		/* TTL threshold 		*/
146	unsigned short	flags;			/* Control flags 		*/
147	int		link;			/* Physical interface index	*/
148};
149
150#define VIFF_STATIC 0x8000
151
152struct mfc6_cache
153{
154	struct mfc6_cache *next;		/* Next entry on cache line 	*/
155	struct in6_addr mf6c_mcastgrp;			/* Group the entry belongs to 	*/
156	struct in6_addr mf6c_origin;			/* Source of packet 		*/
157	mifi_t mf6c_parent;			/* Source interface		*/
158	int mfc_flags;				/* Flags on line		*/
159
160	union {
161		struct {
162			unsigned long expires;
163			struct sk_buff_head unresolved;	/* Unresolved buffers		*/
164		} unres;
165		struct {
166			unsigned long last_assert;
167			int minvif;
168			int maxvif;
169			unsigned long bytes;
170			unsigned long pkt;
171			unsigned long wrong_if;
172			unsigned char ttls[MAXMIFS];	/* TTL thresholds		*/
173		} res;
174	} mfc_un;
175};
176
177#define MFC_STATIC		1
178#define MFC_NOTIFY		2
179
180#define MFC6_LINES		64
181
182#if  (MFC6_LINES & (MFC6_LINES -1 )) == 0
183#define MF6CHASHMOD(h) ((h) & (MFC6_LINES -1))
184#else
185#define MF6CHASHMOD(h) ((h) % MFC6_LINES)
186#endif
187
188#if 0
189#define MFC6_HASH(a, g) MF6CHASHMOD((a).s6_addr32[0] ^ (a).s6_addr32[1] ^ \
190				    (a).s6_addr32[2] ^ (a).s6_addr32[3] ^ \
191				    (a).s6_addr32[0] ^ (a).s6_addr32[1] ^ \
192				    (a).s6_addr32[2] ^ (a).s6_addr32[3])
193#endif
194
195#define MFC6_HASH(a, g) MF6CHASHMOD((a).s6_addr32[0] ^ (a).s6_addr32[1] ^ \
196				    (a).s6_addr32[2] ^ (a).s6_addr32[3])
197
198#endif
199
200
201
202#define MFC_ASSERT_THRESH (3*HZ)		/* Maximal freq. of asserts */
203
204/*
205 *	Pseudo messages used by mrouted
206 */
207
208#define IGMPMSG_NOCACHE		1		/* Kern cache fill request to mrouted */
209#define IGMPMSG_WRONGVIF	2		/* For PIM assert processing (unused) */
210#define IGMPMSG_WHOLEPKT	3		/* For PIM Register processing */
211
212#define PIM_REGISTER		1
213
214#ifdef __KERNEL__
215
216#define PIM_V1_VERSION		__constant_htonl(0x10000000)
217#define PIM_V1_REGISTER		1
218
219#define PIM_VERSION		2
220
221#define PIM_NULL_REGISTER	__constant_htonl(0x40000000)
222
223/* PIMv2 register message header layout (ietf-draft-idmr-pimvsm-v2-00.ps */
224
225struct pim6reghdr
226{
227	__u8	type;
228	__u8	reserved;
229	__u16	csum;
230	__u32	flags;
231};
232
233
234struct rtmsg;
235extern int ip6mr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait);
236#endif
237
238#ifdef __KERNEL__
239
240extern struct sock *mroute6_socket;
241
242#define IN6_ARE_ADDR_EQUAL(a,b) \
243	(memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
244#endif
245
246/*
247 * Structure used to communicate from kernel to multicast router.
248 * We'll overlay the structure onto an MLD header (not an IPv6 heder like igmpmsg{}
249 * used for IPv4 implementation). This is because this structure will be passed via an
250 * IPv6 raw socket, on wich an application will only receiver the payload i.e the data after
251 * the IPv6 header and all the extension headers. (See section 3 of RFC 3542)
252 */
253
254struct mrt6msg {
255#define MRT6MSG_NOCACHE		1
256#define MRT6MSG_WRONGMIF	2
257#define MRT6MSG_WHOLEPKT	3		/* used for use level encap */
258	u_char		im6_mbz;		/* must be zero		   */
259	u_char		im6_msgtype;		/* what type of message    */
260	u_int16_t	im6_mif;		/* mif rec'd on		   */
261	u_int32_t	im6_pad;		/* padding for 64 bit arch */
262	struct in6_addr	im6_src, im6_dst;
263};
264
265/*
266 * PIM packet header
267 */
268#define PIM_VERSION	2
269struct pim {
270#if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
271	u_char	pim_type:4, /* the PIM message type, currently they are:
272			     * Hello, Register, Register-Stop, Join/Prune,
273			     * Bootstrap, Assert, Graft (PIM-DM only),
274			     * Graft-Ack (PIM-DM only), C-RP-Adv
275			     */
276		pim_ver:4;  /* PIM version number; 2 for PIMv2 */
277#else
278	u_char	pim_ver:4,	/* PIM version */
279		pim_type:4;	/* PIM type    */
280#endif
281	u_char  pim_rsv;	/* Reserved */
282	u_short	pim_cksum;	/* IP style check sum */
283};
284
285#define PIM_MINLEN	8		/* The header min. length is 8    */
286#define PIM6_REG_MINLEN	(PIM_MINLEN+40)	/* Register message + inner IP6 header */
287
288#define IPV6_VERSION	0x60
289#define IPV6_VERSION_MASK 0xf0
290
291/* XXX :there should not be there  */
292#include <linux/icmpv6.h>
293
294struct mld_hdr {
295	        struct icmp6hdr mld_icmp6_hdr;
296		        struct in6_addr mld_addr;
297};
298
299#define mld_type mld_icmp6_hdr.icmp6_type
300
301#endif
302