4feb88e5c6
This last patch makes the appropriate changes to use and propagate the network namespace where needed in IPv4 multicast routing code. This consists mainly in replacing all the remaining init_net occurences with current netns pointer retrieved from sockets, net devices or mfc_caches depending on the routines' contexts. Some routines receive a new 'struct net' parameter to propagate the current netns: * vif_add/vif_delete * ipmr_new_tunnel * mroute_clean_tables * ipmr_cache_find * ipmr_cache_report * ipmr_cache_unresolved * ipmr_mfc_add/ipmr_mfc_delete * ipmr_get_route * rt_fill_info (in route.c) Signed-off-by: Benjamin Thery <benjamin.thery@bull.net> Signed-off-by: David S. Miller <davem@davemloft.net>
264 lines
6.4 KiB
C
264 lines
6.4 KiB
C
#ifndef __LINUX_MROUTE_H
|
|
#define __LINUX_MROUTE_H
|
|
|
|
#include <linux/sockios.h>
|
|
#include <linux/types.h>
|
|
#ifdef __KERNEL__
|
|
#include <linux/in.h>
|
|
#endif
|
|
|
|
/*
|
|
* Based on the MROUTING 3.5 defines primarily to keep
|
|
* source compatibility with BSD.
|
|
*
|
|
* See the mrouted code for the original history.
|
|
*
|
|
* Protocol Independent Multicast (PIM) data structures included
|
|
* Carlos Picoto (cap@di.fc.ul.pt)
|
|
*
|
|
*/
|
|
|
|
#define MRT_BASE 200
|
|
#define MRT_INIT (MRT_BASE) /* Activate the kernel mroute code */
|
|
#define MRT_DONE (MRT_BASE+1) /* Shutdown the kernel mroute */
|
|
#define MRT_ADD_VIF (MRT_BASE+2) /* Add a virtual interface */
|
|
#define MRT_DEL_VIF (MRT_BASE+3) /* Delete a virtual interface */
|
|
#define MRT_ADD_MFC (MRT_BASE+4) /* Add a multicast forwarding entry */
|
|
#define MRT_DEL_MFC (MRT_BASE+5) /* Delete a multicast forwarding entry */
|
|
#define MRT_VERSION (MRT_BASE+6) /* Get the kernel multicast version */
|
|
#define MRT_ASSERT (MRT_BASE+7) /* Activate PIM assert mode */
|
|
#define MRT_PIM (MRT_BASE+8) /* enable PIM code */
|
|
|
|
#define SIOCGETVIFCNT SIOCPROTOPRIVATE /* IP protocol privates */
|
|
#define SIOCGETSGCNT (SIOCPROTOPRIVATE+1)
|
|
#define SIOCGETRPF (SIOCPROTOPRIVATE+2)
|
|
|
|
#define MAXVIFS 32
|
|
typedef unsigned long vifbitmap_t; /* User mode code depends on this lot */
|
|
typedef unsigned short vifi_t;
|
|
#define ALL_VIFS ((vifi_t)(-1))
|
|
|
|
/*
|
|
* Same idea as select
|
|
*/
|
|
|
|
#define VIFM_SET(n,m) ((m)|=(1<<(n)))
|
|
#define VIFM_CLR(n,m) ((m)&=~(1<<(n)))
|
|
#define VIFM_ISSET(n,m) ((m)&(1<<(n)))
|
|
#define VIFM_CLRALL(m) ((m)=0)
|
|
#define VIFM_COPY(mfrom,mto) ((mto)=(mfrom))
|
|
#define VIFM_SAME(m1,m2) ((m1)==(m2))
|
|
|
|
/*
|
|
* Passed by mrouted for an MRT_ADD_VIF - again we use the
|
|
* mrouted 3.6 structures for compatibility
|
|
*/
|
|
|
|
struct vifctl {
|
|
vifi_t vifc_vifi; /* Index of VIF */
|
|
unsigned char vifc_flags; /* VIFF_ flags */
|
|
unsigned char vifc_threshold; /* ttl limit */
|
|
unsigned int vifc_rate_limit; /* Rate limiter values (NI) */
|
|
struct in_addr vifc_lcl_addr; /* Our address */
|
|
struct in_addr vifc_rmt_addr; /* IPIP tunnel addr */
|
|
};
|
|
|
|
#define VIFF_TUNNEL 0x1 /* IPIP tunnel */
|
|
#define VIFF_SRCRT 0x2 /* NI */
|
|
#define VIFF_REGISTER 0x4 /* register vif */
|
|
|
|
/*
|
|
* Cache manipulation structures for mrouted and PIMd
|
|
*/
|
|
|
|
struct mfcctl
|
|
{
|
|
struct in_addr mfcc_origin; /* Origin of mcast */
|
|
struct in_addr mfcc_mcastgrp; /* Group in question */
|
|
vifi_t mfcc_parent; /* Where it arrived */
|
|
unsigned char mfcc_ttls[MAXVIFS]; /* Where it is going */
|
|
unsigned int mfcc_pkt_cnt; /* pkt count for src-grp */
|
|
unsigned int mfcc_byte_cnt;
|
|
unsigned int mfcc_wrong_if;
|
|
int mfcc_expire;
|
|
};
|
|
|
|
/*
|
|
* Group count retrieval for mrouted
|
|
*/
|
|
|
|
struct sioc_sg_req
|
|
{
|
|
struct in_addr src;
|
|
struct in_addr grp;
|
|
unsigned long pktcnt;
|
|
unsigned long bytecnt;
|
|
unsigned long wrong_if;
|
|
};
|
|
|
|
/*
|
|
* To get vif packet counts
|
|
*/
|
|
|
|
struct sioc_vif_req
|
|
{
|
|
vifi_t vifi; /* Which iface */
|
|
unsigned long icount; /* In packets */
|
|
unsigned long ocount; /* Out packets */
|
|
unsigned long ibytes; /* In bytes */
|
|
unsigned long obytes; /* Out bytes */
|
|
};
|
|
|
|
/*
|
|
* This is the format the mroute daemon expects to see IGMP control
|
|
* data. Magically happens to be like an IP packet as per the original
|
|
*/
|
|
|
|
struct igmpmsg
|
|
{
|
|
__u32 unused1,unused2;
|
|
unsigned char im_msgtype; /* What is this */
|
|
unsigned char im_mbz; /* Must be zero */
|
|
unsigned char im_vif; /* Interface (this ought to be a vifi_t!) */
|
|
unsigned char unused3;
|
|
struct in_addr im_src,im_dst;
|
|
};
|
|
|
|
/*
|
|
* That's all usermode folks
|
|
*/
|
|
|
|
#ifdef __KERNEL__
|
|
#include <linux/pim.h>
|
|
#include <net/sock.h>
|
|
|
|
#ifdef CONFIG_IP_MROUTE
|
|
static inline int ip_mroute_opt(int opt)
|
|
{
|
|
return (opt >= MRT_BASE) && (opt <= MRT_BASE + 10);
|
|
}
|
|
#else
|
|
static inline int ip_mroute_opt(int opt)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_IP_MROUTE
|
|
extern int ip_mroute_setsockopt(struct sock *, int, char __user *, int);
|
|
extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
|
|
extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
|
|
extern int ip_mr_init(void);
|
|
#else
|
|
static inline
|
|
int ip_mroute_setsockopt(struct sock *sock,
|
|
int optname, char __user *optval, int optlen)
|
|
{
|
|
return -ENOPROTOOPT;
|
|
}
|
|
|
|
static inline
|
|
int ip_mroute_getsockopt(struct sock *sock,
|
|
int optname, char __user *optval, int __user *optlen)
|
|
{
|
|
return -ENOPROTOOPT;
|
|
}
|
|
|
|
static inline
|
|
int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
|
|
{
|
|
return -ENOIOCTLCMD;
|
|
}
|
|
|
|
static inline int ip_mr_init(void)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
struct vif_device
|
|
{
|
|
struct net_device *dev; /* Device we are using */
|
|
unsigned long bytes_in,bytes_out;
|
|
unsigned long pkt_in,pkt_out; /* Statistics */
|
|
unsigned long rate_limit; /* Traffic shaping (NI) */
|
|
unsigned char threshold; /* TTL threshold */
|
|
unsigned short flags; /* Control flags */
|
|
__be32 local,remote; /* Addresses(remote for tunnels)*/
|
|
int link; /* Physical interface index */
|
|
};
|
|
|
|
#define VIFF_STATIC 0x8000
|
|
|
|
struct mfc_cache
|
|
{
|
|
struct mfc_cache *next; /* Next entry on cache line */
|
|
#ifdef CONFIG_NET_NS
|
|
struct net *mfc_net;
|
|
#endif
|
|
__be32 mfc_mcastgrp; /* Group the entry belongs to */
|
|
__be32 mfc_origin; /* Source of packet */
|
|
vifi_t mfc_parent; /* Source interface */
|
|
int mfc_flags; /* Flags on line */
|
|
|
|
union {
|
|
struct {
|
|
unsigned long expires;
|
|
struct sk_buff_head unresolved; /* Unresolved buffers */
|
|
} unres;
|
|
struct {
|
|
unsigned long last_assert;
|
|
int minvif;
|
|
int maxvif;
|
|
unsigned long bytes;
|
|
unsigned long pkt;
|
|
unsigned long wrong_if;
|
|
unsigned char ttls[MAXVIFS]; /* TTL thresholds */
|
|
} res;
|
|
} mfc_un;
|
|
};
|
|
|
|
static inline
|
|
struct net *mfc_net(const struct mfc_cache *mfc)
|
|
{
|
|
return read_pnet(&mfc->mfc_net);
|
|
}
|
|
|
|
static inline
|
|
void mfc_net_set(struct mfc_cache *mfc, struct net *net)
|
|
{
|
|
write_pnet(&mfc->mfc_net, hold_net(net));
|
|
}
|
|
|
|
#define MFC_STATIC 1
|
|
#define MFC_NOTIFY 2
|
|
|
|
#define MFC_LINES 64
|
|
|
|
#ifdef __BIG_ENDIAN
|
|
#define MFC_HASH(a,b) (((((__force u32)(__be32)a)>>24)^(((__force u32)(__be32)b)>>26))&(MFC_LINES-1))
|
|
#else
|
|
#define MFC_HASH(a,b) ((((__force u32)(__be32)a)^(((__force u32)(__be32)b)>>2))&(MFC_LINES-1))
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
#define MFC_ASSERT_THRESH (3*HZ) /* Maximal freq. of asserts */
|
|
|
|
/*
|
|
* Pseudo messages used by mrouted
|
|
*/
|
|
|
|
#define IGMPMSG_NOCACHE 1 /* Kern cache fill request to mrouted */
|
|
#define IGMPMSG_WRONGVIF 2 /* For PIM assert processing (unused) */
|
|
#define IGMPMSG_WHOLEPKT 3 /* For PIM Register processing */
|
|
|
|
#ifdef __KERNEL__
|
|
struct rtmsg;
|
|
extern int ipmr_get_route(struct net *net, struct sk_buff *skb,
|
|
struct rtmsg *rtm, int nowait);
|
|
#endif
|
|
|
|
#endif
|