mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/ipmr-2.6
This commit is contained in:
commit
bb61187465
@ -15,14 +15,6 @@
|
|||||||
/* try to find source address in routing lookups */
|
/* try to find source address in routing lookups */
|
||||||
#define FIB_RULE_FIND_SADDR 0x00010000
|
#define FIB_RULE_FIND_SADDR 0x00010000
|
||||||
|
|
||||||
/* fib_rules families. values up to 127 are reserved for real address
|
|
||||||
* families, values above 128 may be used arbitrarily.
|
|
||||||
*/
|
|
||||||
#define FIB_RULES_IPV4 AF_INET
|
|
||||||
#define FIB_RULES_IPV6 AF_INET6
|
|
||||||
#define FIB_RULES_DECNET AF_DECnet
|
|
||||||
#define FIB_RULES_IPMR 128
|
|
||||||
|
|
||||||
struct fib_rule_hdr {
|
struct fib_rule_hdr {
|
||||||
__u8 family;
|
__u8 family;
|
||||||
__u8 dst_len;
|
__u8 dst_len;
|
||||||
|
@ -7,6 +7,12 @@
|
|||||||
#include <linux/if_addr.h>
|
#include <linux/if_addr.h>
|
||||||
#include <linux/neighbour.h>
|
#include <linux/neighbour.h>
|
||||||
|
|
||||||
|
/* rtnetlink families. Values up to 127 are reserved for real address
|
||||||
|
* families, values above 128 may be used arbitrarily.
|
||||||
|
*/
|
||||||
|
#define RTNL_FAMILY_IPMR 128
|
||||||
|
#define RTNL_FAMILY_MAX 128
|
||||||
|
|
||||||
/****
|
/****
|
||||||
* Routing/neighbour discovery messages.
|
* Routing/neighbour discovery messages.
|
||||||
****/
|
****/
|
||||||
|
@ -104,7 +104,7 @@ static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
|
|||||||
return frh->table;
|
return frh->table;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern struct fib_rules_ops *fib_rules_register(struct fib_rules_ops *, struct net *);
|
extern struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *, struct net *);
|
||||||
extern void fib_rules_unregister(struct fib_rules_ops *);
|
extern void fib_rules_unregister(struct fib_rules_ops *);
|
||||||
extern void fib_rules_cleanup_ops(struct fib_rules_ops *);
|
extern void fib_rules_cleanup_ops(struct fib_rules_ops *);
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ errout:
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct fib_rules_ops *
|
struct fib_rules_ops *
|
||||||
fib_rules_register(struct fib_rules_ops *tmpl, struct net *net)
|
fib_rules_register(const struct fib_rules_ops *tmpl, struct net *net)
|
||||||
{
|
{
|
||||||
struct fib_rules_ops *ops;
|
struct fib_rules_ops *ops;
|
||||||
int err;
|
int err;
|
||||||
|
@ -98,7 +98,7 @@ int lockdep_rtnl_is_held(void)
|
|||||||
EXPORT_SYMBOL(lockdep_rtnl_is_held);
|
EXPORT_SYMBOL(lockdep_rtnl_is_held);
|
||||||
#endif /* #ifdef CONFIG_PROVE_LOCKING */
|
#endif /* #ifdef CONFIG_PROVE_LOCKING */
|
||||||
|
|
||||||
static struct rtnl_link *rtnl_msg_handlers[NPROTO];
|
static struct rtnl_link *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1];
|
||||||
|
|
||||||
static inline int rtm_msgindex(int msgtype)
|
static inline int rtm_msgindex(int msgtype)
|
||||||
{
|
{
|
||||||
@ -118,7 +118,7 @@ static rtnl_doit_func rtnl_get_doit(int protocol, int msgindex)
|
|||||||
{
|
{
|
||||||
struct rtnl_link *tab;
|
struct rtnl_link *tab;
|
||||||
|
|
||||||
if (protocol < NPROTO)
|
if (protocol <= RTNL_FAMILY_MAX)
|
||||||
tab = rtnl_msg_handlers[protocol];
|
tab = rtnl_msg_handlers[protocol];
|
||||||
else
|
else
|
||||||
tab = NULL;
|
tab = NULL;
|
||||||
@ -133,7 +133,7 @@ static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex)
|
|||||||
{
|
{
|
||||||
struct rtnl_link *tab;
|
struct rtnl_link *tab;
|
||||||
|
|
||||||
if (protocol < NPROTO)
|
if (protocol <= RTNL_FAMILY_MAX)
|
||||||
tab = rtnl_msg_handlers[protocol];
|
tab = rtnl_msg_handlers[protocol];
|
||||||
else
|
else
|
||||||
tab = NULL;
|
tab = NULL;
|
||||||
@ -167,7 +167,7 @@ int __rtnl_register(int protocol, int msgtype,
|
|||||||
struct rtnl_link *tab;
|
struct rtnl_link *tab;
|
||||||
int msgindex;
|
int msgindex;
|
||||||
|
|
||||||
BUG_ON(protocol < 0 || protocol >= NPROTO);
|
BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
|
||||||
msgindex = rtm_msgindex(msgtype);
|
msgindex = rtm_msgindex(msgtype);
|
||||||
|
|
||||||
tab = rtnl_msg_handlers[protocol];
|
tab = rtnl_msg_handlers[protocol];
|
||||||
@ -219,7 +219,7 @@ int rtnl_unregister(int protocol, int msgtype)
|
|||||||
{
|
{
|
||||||
int msgindex;
|
int msgindex;
|
||||||
|
|
||||||
BUG_ON(protocol < 0 || protocol >= NPROTO);
|
BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
|
||||||
msgindex = rtm_msgindex(msgtype);
|
msgindex = rtm_msgindex(msgtype);
|
||||||
|
|
||||||
if (rtnl_msg_handlers[protocol] == NULL)
|
if (rtnl_msg_handlers[protocol] == NULL)
|
||||||
@ -241,7 +241,7 @@ EXPORT_SYMBOL_GPL(rtnl_unregister);
|
|||||||
*/
|
*/
|
||||||
void rtnl_unregister_all(int protocol)
|
void rtnl_unregister_all(int protocol)
|
||||||
{
|
{
|
||||||
BUG_ON(protocol < 0 || protocol >= NPROTO);
|
BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
|
||||||
|
|
||||||
kfree(rtnl_msg_handlers[protocol]);
|
kfree(rtnl_msg_handlers[protocol]);
|
||||||
rtnl_msg_handlers[protocol] = NULL;
|
rtnl_msg_handlers[protocol] = NULL;
|
||||||
@ -1385,7 +1385,7 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
|
|||||||
|
|
||||||
if (s_idx == 0)
|
if (s_idx == 0)
|
||||||
s_idx = 1;
|
s_idx = 1;
|
||||||
for (idx = 1; idx < NPROTO; idx++) {
|
for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) {
|
||||||
int type = cb->nlh->nlmsg_type-RTM_BASE;
|
int type = cb->nlh->nlmsg_type-RTM_BASE;
|
||||||
if (idx < s_idx || idx == PF_PACKET)
|
if (idx < s_idx || idx == PF_PACKET)
|
||||||
continue;
|
continue;
|
||||||
|
@ -216,8 +216,8 @@ static void dn_fib_rule_flush_cache(struct fib_rules_ops *ops)
|
|||||||
dn_rt_cache_flush(-1);
|
dn_rt_cache_flush(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct fib_rules_ops dn_fib_rules_ops_template = {
|
static const struct fib_rules_ops __net_initdata dn_fib_rules_ops_template = {
|
||||||
.family = FIB_RULES_DECNET,
|
.family = AF_DECnet,
|
||||||
.rule_size = sizeof(struct dn_fib_rule),
|
.rule_size = sizeof(struct dn_fib_rule),
|
||||||
.addr_size = sizeof(u16),
|
.addr_size = sizeof(u16),
|
||||||
.action = dn_fib_rule_action,
|
.action = dn_fib_rule_action,
|
||||||
|
@ -245,8 +245,8 @@ static void fib4_rule_flush_cache(struct fib_rules_ops *ops)
|
|||||||
rt_cache_flush(ops->fro_net, -1);
|
rt_cache_flush(ops->fro_net, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct fib_rules_ops fib4_rules_ops_template = {
|
static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = {
|
||||||
.family = FIB_RULES_IPV4,
|
.family = AF_INET,
|
||||||
.rule_size = sizeof(struct fib4_rule),
|
.rule_size = sizeof(struct fib4_rule),
|
||||||
.addr_size = sizeof(u32),
|
.addr_size = sizeof(u32),
|
||||||
.action = fib4_rule_action,
|
.action = fib4_rule_action,
|
||||||
|
100
net/ipv4/ipmr.c
100
net/ipv4/ipmr.c
@ -128,8 +128,8 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt,
|
|||||||
int local);
|
int local);
|
||||||
static int ipmr_cache_report(struct mr_table *mrt,
|
static int ipmr_cache_report(struct mr_table *mrt,
|
||||||
struct sk_buff *pkt, vifi_t vifi, int assert);
|
struct sk_buff *pkt, vifi_t vifi, int assert);
|
||||||
static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
|
static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
|
||||||
struct mfc_cache *c, struct rtmsg *rtm);
|
struct mfc_cache *c, struct rtmsg *rtm);
|
||||||
static void ipmr_expire_process(unsigned long arg);
|
static void ipmr_expire_process(unsigned long arg);
|
||||||
|
|
||||||
#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
|
#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
|
||||||
@ -216,8 +216,8 @@ static int ipmr_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct fib_rules_ops ipmr_rules_ops_template = {
|
static const struct fib_rules_ops __net_initdata ipmr_rules_ops_template = {
|
||||||
.family = FIB_RULES_IPMR,
|
.family = RTNL_FAMILY_IPMR,
|
||||||
.rule_size = sizeof(struct ipmr_rule),
|
.rule_size = sizeof(struct ipmr_rule),
|
||||||
.addr_size = sizeof(u32),
|
.addr_size = sizeof(u32),
|
||||||
.action = ipmr_rule_action,
|
.action = ipmr_rule_action,
|
||||||
@ -831,7 +831,7 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
|
|||||||
if (ip_hdr(skb)->version == 0) {
|
if (ip_hdr(skb)->version == 0) {
|
||||||
struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr));
|
struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr));
|
||||||
|
|
||||||
if (ipmr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) {
|
if (__ipmr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) {
|
||||||
nlh->nlmsg_len = (skb_tail_pointer(skb) -
|
nlh->nlmsg_len = (skb_tail_pointer(skb) -
|
||||||
(u8 *)nlh);
|
(u8 *)nlh);
|
||||||
} else {
|
} else {
|
||||||
@ -1904,9 +1904,8 @@ drop:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
|
||||||
ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, struct mfc_cache *c,
|
struct mfc_cache *c, struct rtmsg *rtm)
|
||||||
struct rtmsg *rtm)
|
|
||||||
{
|
{
|
||||||
int ct;
|
int ct;
|
||||||
struct rtnexthop *nhp;
|
struct rtnexthop *nhp;
|
||||||
@ -1994,11 +1993,93 @@ int ipmr_get_route(struct net *net,
|
|||||||
|
|
||||||
if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY))
|
if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY))
|
||||||
cache->mfc_flags |= MFC_NOTIFY;
|
cache->mfc_flags |= MFC_NOTIFY;
|
||||||
err = ipmr_fill_mroute(mrt, skb, cache, rtm);
|
err = __ipmr_fill_mroute(mrt, skb, cache, rtm);
|
||||||
read_unlock(&mrt_lock);
|
read_unlock(&mrt_lock);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
|
||||||
|
u32 pid, u32 seq, struct mfc_cache *c)
|
||||||
|
{
|
||||||
|
struct nlmsghdr *nlh;
|
||||||
|
struct rtmsg *rtm;
|
||||||
|
|
||||||
|
nlh = nlmsg_put(skb, pid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI);
|
||||||
|
if (nlh == NULL)
|
||||||
|
return -EMSGSIZE;
|
||||||
|
|
||||||
|
rtm = nlmsg_data(nlh);
|
||||||
|
rtm->rtm_family = RTNL_FAMILY_IPMR;
|
||||||
|
rtm->rtm_dst_len = 32;
|
||||||
|
rtm->rtm_src_len = 32;
|
||||||
|
rtm->rtm_tos = 0;
|
||||||
|
rtm->rtm_table = mrt->id;
|
||||||
|
NLA_PUT_U32(skb, RTA_TABLE, mrt->id);
|
||||||
|
rtm->rtm_type = RTN_MULTICAST;
|
||||||
|
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
|
||||||
|
rtm->rtm_protocol = RTPROT_UNSPEC;
|
||||||
|
rtm->rtm_flags = 0;
|
||||||
|
|
||||||
|
NLA_PUT_BE32(skb, RTA_SRC, c->mfc_origin);
|
||||||
|
NLA_PUT_BE32(skb, RTA_DST, c->mfc_mcastgrp);
|
||||||
|
|
||||||
|
if (__ipmr_fill_mroute(mrt, skb, c, rtm) < 0)
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
return nlmsg_end(skb, nlh);
|
||||||
|
|
||||||
|
nla_put_failure:
|
||||||
|
nlmsg_cancel(skb, nlh);
|
||||||
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
|
{
|
||||||
|
struct net *net = sock_net(skb->sk);
|
||||||
|
struct mr_table *mrt;
|
||||||
|
struct mfc_cache *mfc;
|
||||||
|
unsigned int t = 0, s_t;
|
||||||
|
unsigned int h = 0, s_h;
|
||||||
|
unsigned int e = 0, s_e;
|
||||||
|
|
||||||
|
s_t = cb->args[0];
|
||||||
|
s_h = cb->args[1];
|
||||||
|
s_e = cb->args[2];
|
||||||
|
|
||||||
|
read_lock(&mrt_lock);
|
||||||
|
ipmr_for_each_table(mrt, net) {
|
||||||
|
if (t < s_t)
|
||||||
|
goto next_table;
|
||||||
|
if (t > s_t)
|
||||||
|
s_h = 0;
|
||||||
|
for (h = s_h; h < MFC_LINES; h++) {
|
||||||
|
list_for_each_entry(mfc, &mrt->mfc_cache_array[h], list) {
|
||||||
|
if (e < s_e)
|
||||||
|
goto next_entry;
|
||||||
|
if (ipmr_fill_mroute(mrt, skb,
|
||||||
|
NETLINK_CB(cb->skb).pid,
|
||||||
|
cb->nlh->nlmsg_seq,
|
||||||
|
mfc) < 0)
|
||||||
|
goto done;
|
||||||
|
next_entry:
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
e = s_e = 0;
|
||||||
|
}
|
||||||
|
s_h = 0;
|
||||||
|
next_table:
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
read_unlock(&mrt_lock);
|
||||||
|
|
||||||
|
cb->args[2] = e;
|
||||||
|
cb->args[1] = h;
|
||||||
|
cb->args[0] = t;
|
||||||
|
|
||||||
|
return skb->len;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
/*
|
/*
|
||||||
* The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif
|
* The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif
|
||||||
@ -2355,6 +2436,7 @@ int __init ip_mr_init(void)
|
|||||||
goto add_proto_fail;
|
goto add_proto_fail;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
rtnl_register(RTNL_FAMILY_IPMR, RTM_GETROUTE, NULL, ipmr_rtm_dumproute);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef CONFIG_IP_PIMSM_V2
|
#ifdef CONFIG_IP_PIMSM_V2
|
||||||
|
@ -237,8 +237,8 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule)
|
|||||||
+ nla_total_size(16); /* src */
|
+ nla_total_size(16); /* src */
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct fib_rules_ops fib6_rules_ops_template = {
|
static const struct fib_rules_ops __net_initdata fib6_rules_ops_template = {
|
||||||
.family = FIB_RULES_IPV6,
|
.family = AF_INET6,
|
||||||
.rule_size = sizeof(struct fib6_rule),
|
.rule_size = sizeof(struct fib6_rule),
|
||||||
.addr_size = sizeof(struct in6_addr),
|
.addr_size = sizeof(struct in6_addr),
|
||||||
.action = fib6_rule_action,
|
.action = fib6_rule_action,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user