gtp: add dump operation
I also added the skeleton of the get operation. Signed-off-by: Pablo Neira Ayuso <pablo@gnumonks.org>
This commit is contained in:
parent
85dfd1ab09
commit
ccf3095e6e
107
gtp.c
107
gtp.c
|
@ -124,6 +124,8 @@ struct gtp_instance {
|
|||
struct hlist_head *addr_hash;
|
||||
};
|
||||
|
||||
static LIST_HEAD(gtp_instance_list); /* XXX netns */
|
||||
|
||||
static inline uint32_t gtp0_hashfn(uint64_t tid)
|
||||
{
|
||||
uint32_t *tid32 = (uint32_t *) &tid;
|
||||
|
@ -661,6 +663,8 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
|
|||
if (err < 0)
|
||||
goto err1;
|
||||
|
||||
list_add_rcu(>i->list, >p_instance_list);
|
||||
|
||||
pr_info("registered new netdev\n");
|
||||
|
||||
return 0;
|
||||
|
@ -671,7 +675,10 @@ err1:
|
|||
|
||||
static void gtp_dellink(struct net_device *dev, struct list_head *head)
|
||||
{
|
||||
struct gtp_instance *gti = netdev_priv(dev);
|
||||
|
||||
unregister_netdevice_queue(dev, head);
|
||||
list_del_rcu(>i->list);
|
||||
}
|
||||
|
||||
static int gtp_changelink(struct net_device *dev, struct nlattr *tb[],
|
||||
|
@ -888,12 +895,99 @@ static int gtp_genl_tunnel_delete(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
static int gtp_genl_tunnel_get(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct net_device *dev;
|
||||
|
||||
pr_info("get tunnel\n");
|
||||
|
||||
if (!info->attrs[GTPA_VERSION] ||
|
||||
!info->attrs[GTPA_LINK])
|
||||
return -EINVAL;
|
||||
|
||||
dev = dev_get_by_index(net, nla_get_u32(info->attrs[GTPA_LINK]));
|
||||
if (dev == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
if (strncmp(dev->name, "gtp", 3) != 0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (info->attrs[GTPA_TID])
|
||||
pr_info("by tid\n");
|
||||
else if (info->attrs[GTPA_MS_ADDRESS])
|
||||
pr_info("by ms\n");
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gtp_genl_tunnel_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
static struct genl_family gtp_genl_family = {
|
||||
.id = GENL_ID_GENERATE,
|
||||
.name = "gtp",
|
||||
.version = 0,
|
||||
.hdrsize = 0,
|
||||
.maxattr = GTPA_MAX,
|
||||
.netnsok = true,
|
||||
};
|
||||
|
||||
static int
|
||||
gtp_genl_fill_info(struct sk_buff *skb, uint32_t snd_portid, uint32_t snd_seq,
|
||||
uint32_t type, struct pdp_ctx *pctx)
|
||||
{
|
||||
return 0;
|
||||
void *genlh;
|
||||
|
||||
genlh = genlmsg_put(skb, snd_portid, snd_seq, >p_genl_family, 0,
|
||||
type);
|
||||
if (genlh == NULL)
|
||||
goto nlmsg_failure;
|
||||
|
||||
if (nla_put_u32(skb, GTPA_VERSION, pctx->tid) ||
|
||||
nla_put_u32(skb, GTPA_SGSN_ADDRESS, pctx->sgsn_addr.ip4) ||
|
||||
nla_put_u32(skb, GTPA_MS_ADDRESS, pctx->ms_addr.ip4) ||
|
||||
nla_put_u32(skb, GTPA_TID, pctx->tid))
|
||||
goto nla_put_failure;
|
||||
|
||||
return genlmsg_end(skb, genlh);
|
||||
|
||||
nlmsg_failure:
|
||||
nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static int
|
||||
gtp_genl_tunnel_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
int i, k = cb->args[0], tid = cb->args[1], ret;
|
||||
struct gtp_instance *last_gti = (struct gtp_instance *)cb->args[2], *gti;
|
||||
struct pdp_ctx *pctx;
|
||||
|
||||
list_for_each_entry_rcu(gti, >p_instance_list, list) {
|
||||
if (last_gti && last_gti != gti)
|
||||
continue;
|
||||
else
|
||||
last_gti = NULL;
|
||||
|
||||
for (i = k; i < gti->hash_size; i++) {
|
||||
hlist_for_each_entry_rcu(pctx, >i->addr_hash[i], hlist_tid) {
|
||||
if (tid && tid != pctx->tid)
|
||||
continue;
|
||||
else
|
||||
tid = 0;
|
||||
|
||||
ret = gtp_genl_fill_info(skb,
|
||||
NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq,
|
||||
cb->nlh->nlmsg_type, pctx);
|
||||
if (ret < 0) {
|
||||
cb->args[0] = i;
|
||||
cb->args[1] = pctx->tid;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
return skb->len;
|
||||
}
|
||||
|
||||
static struct nla_policy gtp_genl_policy[GTPA_MAX + 1] = {
|
||||
|
@ -925,15 +1019,6 @@ static const struct genl_ops gtp_genl_ops[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct genl_family gtp_genl_family = {
|
||||
.id = GENL_ID_GENERATE,
|
||||
.name = "gtp",
|
||||
.version = 0,
|
||||
.hdrsize = 0,
|
||||
.maxattr = GTPA_MAX,
|
||||
.netnsok = true,
|
||||
};
|
||||
|
||||
static int __init gtp_init(void)
|
||||
{
|
||||
int err;
|
||||
|
|
Loading…
Reference in New Issue