1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2016 Jonas Johansson <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker */
5*4dc78e53SAndroid Build Coastguard Worker
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker * @ingroup link
8*4dc78e53SAndroid Build Coastguard Worker * @defgroup ppp PPP
9*4dc78e53SAndroid Build Coastguard Worker *
10*4dc78e53SAndroid Build Coastguard Worker * @details
11*4dc78e53SAndroid Build Coastguard Worker * \b Link Type Name: "ppp"
12*4dc78e53SAndroid Build Coastguard Worker *
13*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_ppp, PPP Documentation}
14*4dc78e53SAndroid Build Coastguard Worker * @{
15*4dc78e53SAndroid Build Coastguard Worker */
16*4dc78e53SAndroid Build Coastguard Worker
17*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
18*4dc78e53SAndroid Build Coastguard Worker
19*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/link/ppp.h>
20*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
21*4dc78e53SAndroid Build Coastguard Worker
22*4dc78e53SAndroid Build Coastguard Worker #include "nl-route.h"
23*4dc78e53SAndroid Build Coastguard Worker #include "link-api.h"
24*4dc78e53SAndroid Build Coastguard Worker
25*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
26*4dc78e53SAndroid Build Coastguard Worker #define PPP_ATTR_FD (1<<0)
27*4dc78e53SAndroid Build Coastguard Worker
28*4dc78e53SAndroid Build Coastguard Worker struct ppp_info
29*4dc78e53SAndroid Build Coastguard Worker {
30*4dc78e53SAndroid Build Coastguard Worker int32_t pi_fd;
31*4dc78e53SAndroid Build Coastguard Worker uint32_t ce_mask;
32*4dc78e53SAndroid Build Coastguard Worker };
33*4dc78e53SAndroid Build Coastguard Worker
34*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
35*4dc78e53SAndroid Build Coastguard Worker
36*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy ppp_nl_policy[IFLA_PPP_MAX+1] = {
37*4dc78e53SAndroid Build Coastguard Worker [IFLA_PPP_DEV_FD] = { .type = NLA_S32 },
38*4dc78e53SAndroid Build Coastguard Worker };
39*4dc78e53SAndroid Build Coastguard Worker
ppp_alloc(struct rtnl_link * link)40*4dc78e53SAndroid Build Coastguard Worker static int ppp_alloc(struct rtnl_link *link)
41*4dc78e53SAndroid Build Coastguard Worker {
42*4dc78e53SAndroid Build Coastguard Worker struct ppp_info *info;
43*4dc78e53SAndroid Build Coastguard Worker
44*4dc78e53SAndroid Build Coastguard Worker if (link->l_info)
45*4dc78e53SAndroid Build Coastguard Worker memset(link->l_info, 0, sizeof(*info));
46*4dc78e53SAndroid Build Coastguard Worker else {
47*4dc78e53SAndroid Build Coastguard Worker if ((info = calloc(1, sizeof(*info))) == NULL)
48*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
49*4dc78e53SAndroid Build Coastguard Worker
50*4dc78e53SAndroid Build Coastguard Worker link->l_info = info;
51*4dc78e53SAndroid Build Coastguard Worker }
52*4dc78e53SAndroid Build Coastguard Worker
53*4dc78e53SAndroid Build Coastguard Worker return 0;
54*4dc78e53SAndroid Build Coastguard Worker }
55*4dc78e53SAndroid Build Coastguard Worker
ppp_parse(struct rtnl_link * link,struct nlattr * data,struct nlattr * xstats)56*4dc78e53SAndroid Build Coastguard Worker static int ppp_parse(struct rtnl_link *link, struct nlattr *data,
57*4dc78e53SAndroid Build Coastguard Worker struct nlattr *xstats)
58*4dc78e53SAndroid Build Coastguard Worker {
59*4dc78e53SAndroid Build Coastguard Worker struct nlattr *tb[IFLA_PPP_MAX+1];
60*4dc78e53SAndroid Build Coastguard Worker struct ppp_info *info;
61*4dc78e53SAndroid Build Coastguard Worker int err;
62*4dc78e53SAndroid Build Coastguard Worker
63*4dc78e53SAndroid Build Coastguard Worker NL_DBG(3, "Parsing PPP link info\n");
64*4dc78e53SAndroid Build Coastguard Worker
65*4dc78e53SAndroid Build Coastguard Worker if ((err = nla_parse_nested(tb, IFLA_PPP_MAX, data, ppp_nl_policy)) < 0)
66*4dc78e53SAndroid Build Coastguard Worker goto errout;
67*4dc78e53SAndroid Build Coastguard Worker
68*4dc78e53SAndroid Build Coastguard Worker if ((err = ppp_alloc(link)) < 0)
69*4dc78e53SAndroid Build Coastguard Worker goto errout;
70*4dc78e53SAndroid Build Coastguard Worker
71*4dc78e53SAndroid Build Coastguard Worker info = link->l_info;
72*4dc78e53SAndroid Build Coastguard Worker
73*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_PPP_DEV_FD]) {
74*4dc78e53SAndroid Build Coastguard Worker info->pi_fd = nla_get_s32(tb[IFLA_PPP_DEV_FD]);
75*4dc78e53SAndroid Build Coastguard Worker info->ce_mask |= PPP_ATTR_FD;
76*4dc78e53SAndroid Build Coastguard Worker }
77*4dc78e53SAndroid Build Coastguard Worker
78*4dc78e53SAndroid Build Coastguard Worker err = 0;
79*4dc78e53SAndroid Build Coastguard Worker errout:
80*4dc78e53SAndroid Build Coastguard Worker return err;
81*4dc78e53SAndroid Build Coastguard Worker }
82*4dc78e53SAndroid Build Coastguard Worker
ppp_free(struct rtnl_link * link)83*4dc78e53SAndroid Build Coastguard Worker static void ppp_free(struct rtnl_link *link)
84*4dc78e53SAndroid Build Coastguard Worker {
85*4dc78e53SAndroid Build Coastguard Worker free(link->l_info);
86*4dc78e53SAndroid Build Coastguard Worker link->l_info = NULL;
87*4dc78e53SAndroid Build Coastguard Worker }
88*4dc78e53SAndroid Build Coastguard Worker
ppp_clone(struct rtnl_link * dst,struct rtnl_link * src)89*4dc78e53SAndroid Build Coastguard Worker static int ppp_clone(struct rtnl_link *dst, struct rtnl_link *src)
90*4dc78e53SAndroid Build Coastguard Worker {
91*4dc78e53SAndroid Build Coastguard Worker struct ppp_info *vdst, *vsrc = src->l_info;
92*4dc78e53SAndroid Build Coastguard Worker int err;
93*4dc78e53SAndroid Build Coastguard Worker
94*4dc78e53SAndroid Build Coastguard Worker dst->l_info = NULL;
95*4dc78e53SAndroid Build Coastguard Worker if ((err = rtnl_link_set_type(dst, "ppp")) < 0)
96*4dc78e53SAndroid Build Coastguard Worker return err;
97*4dc78e53SAndroid Build Coastguard Worker vdst = dst->l_info;
98*4dc78e53SAndroid Build Coastguard Worker
99*4dc78e53SAndroid Build Coastguard Worker if (!vdst || !vsrc)
100*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
101*4dc78e53SAndroid Build Coastguard Worker
102*4dc78e53SAndroid Build Coastguard Worker memcpy(vdst, vsrc, sizeof(struct ppp_info));
103*4dc78e53SAndroid Build Coastguard Worker
104*4dc78e53SAndroid Build Coastguard Worker return 0;
105*4dc78e53SAndroid Build Coastguard Worker }
106*4dc78e53SAndroid Build Coastguard Worker
ppp_put_attrs(struct nl_msg * msg,struct rtnl_link * link)107*4dc78e53SAndroid Build Coastguard Worker static int ppp_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
108*4dc78e53SAndroid Build Coastguard Worker {
109*4dc78e53SAndroid Build Coastguard Worker struct ppp_info *info = link->l_info;
110*4dc78e53SAndroid Build Coastguard Worker struct nlattr *data;
111*4dc78e53SAndroid Build Coastguard Worker
112*4dc78e53SAndroid Build Coastguard Worker if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
113*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSGSIZE;
114*4dc78e53SAndroid Build Coastguard Worker
115*4dc78e53SAndroid Build Coastguard Worker if (info->ce_mask & PPP_ATTR_FD)
116*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_S32(msg, IFLA_PPP_DEV_FD, info->pi_fd);
117*4dc78e53SAndroid Build Coastguard Worker
118*4dc78e53SAndroid Build Coastguard Worker nla_nest_end(msg, data);
119*4dc78e53SAndroid Build Coastguard Worker
120*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
121*4dc78e53SAndroid Build Coastguard Worker
122*4dc78e53SAndroid Build Coastguard Worker return 0;
123*4dc78e53SAndroid Build Coastguard Worker }
124*4dc78e53SAndroid Build Coastguard Worker
125*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_link_info_ops ppp_info_ops = {
126*4dc78e53SAndroid Build Coastguard Worker .io_name = "ppp",
127*4dc78e53SAndroid Build Coastguard Worker .io_alloc = ppp_alloc,
128*4dc78e53SAndroid Build Coastguard Worker .io_parse = ppp_parse,
129*4dc78e53SAndroid Build Coastguard Worker .io_clone = ppp_clone,
130*4dc78e53SAndroid Build Coastguard Worker .io_put_attrs = ppp_put_attrs,
131*4dc78e53SAndroid Build Coastguard Worker .io_free = ppp_free,
132*4dc78e53SAndroid Build Coastguard Worker };
133*4dc78e53SAndroid Build Coastguard Worker
134*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
135*4dc78e53SAndroid Build Coastguard Worker #define IS_PPP_LINK_ASSERT(link) \
136*4dc78e53SAndroid Build Coastguard Worker if ((link)->l_info_ops != &ppp_info_ops) { \
137*4dc78e53SAndroid Build Coastguard Worker APPBUG("Link is not a PPP link. set type \"ppp\" first."); \
138*4dc78e53SAndroid Build Coastguard Worker return -NLE_OPNOTSUPP; \
139*4dc78e53SAndroid Build Coastguard Worker }
140*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
141*4dc78e53SAndroid Build Coastguard Worker
142*4dc78e53SAndroid Build Coastguard Worker /**
143*4dc78e53SAndroid Build Coastguard Worker * @name PPP Object
144*4dc78e53SAndroid Build Coastguard Worker * @{
145*4dc78e53SAndroid Build Coastguard Worker */
146*4dc78e53SAndroid Build Coastguard Worker
147*4dc78e53SAndroid Build Coastguard Worker /**
148*4dc78e53SAndroid Build Coastguard Worker * Allocate link object of type PPP
149*4dc78e53SAndroid Build Coastguard Worker *
150*4dc78e53SAndroid Build Coastguard Worker * @return Allocated link object or NULL.
151*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_ppp_alloc(void)152*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *rtnl_link_ppp_alloc(void)
153*4dc78e53SAndroid Build Coastguard Worker {
154*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *link;
155*4dc78e53SAndroid Build Coastguard Worker
156*4dc78e53SAndroid Build Coastguard Worker if (!(link = rtnl_link_alloc()))
157*4dc78e53SAndroid Build Coastguard Worker return NULL;
158*4dc78e53SAndroid Build Coastguard Worker
159*4dc78e53SAndroid Build Coastguard Worker if (rtnl_link_set_type(link, "ppp") < 0) {
160*4dc78e53SAndroid Build Coastguard Worker rtnl_link_put(link);
161*4dc78e53SAndroid Build Coastguard Worker return NULL;
162*4dc78e53SAndroid Build Coastguard Worker }
163*4dc78e53SAndroid Build Coastguard Worker
164*4dc78e53SAndroid Build Coastguard Worker return link;
165*4dc78e53SAndroid Build Coastguard Worker }
166*4dc78e53SAndroid Build Coastguard Worker
167*4dc78e53SAndroid Build Coastguard Worker /**
168*4dc78e53SAndroid Build Coastguard Worker * Set PPP file descriptor
169*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
170*4dc78e53SAndroid Build Coastguard Worker * @arg flags PPP file descriptor
171*4dc78e53SAndroid Build Coastguard Worker *
172*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
173*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_ppp_set_fd(struct rtnl_link * link,int32_t fd)174*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_ppp_set_fd(struct rtnl_link *link, int32_t fd)
175*4dc78e53SAndroid Build Coastguard Worker {
176*4dc78e53SAndroid Build Coastguard Worker struct ppp_info *info = link->l_info;
177*4dc78e53SAndroid Build Coastguard Worker
178*4dc78e53SAndroid Build Coastguard Worker IS_PPP_LINK_ASSERT(link);
179*4dc78e53SAndroid Build Coastguard Worker
180*4dc78e53SAndroid Build Coastguard Worker info->pi_fd |= fd;
181*4dc78e53SAndroid Build Coastguard Worker info->ce_mask |= PPP_ATTR_FD;
182*4dc78e53SAndroid Build Coastguard Worker
183*4dc78e53SAndroid Build Coastguard Worker return 0;
184*4dc78e53SAndroid Build Coastguard Worker }
185*4dc78e53SAndroid Build Coastguard Worker
186*4dc78e53SAndroid Build Coastguard Worker /**
187*4dc78e53SAndroid Build Coastguard Worker * Get PPP file descriptor
188*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
189*4dc78e53SAndroid Build Coastguard Worker *
190*4dc78e53SAndroid Build Coastguard Worker * @return PPP file descriptor, 0 if not set or a negative error code.
191*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_ppp_get_fd(struct rtnl_link * link,int32_t * fd)192*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_ppp_get_fd(struct rtnl_link *link, int32_t *fd)
193*4dc78e53SAndroid Build Coastguard Worker {
194*4dc78e53SAndroid Build Coastguard Worker struct ppp_info *info = link->l_info;
195*4dc78e53SAndroid Build Coastguard Worker
196*4dc78e53SAndroid Build Coastguard Worker IS_PPP_LINK_ASSERT(link);
197*4dc78e53SAndroid Build Coastguard Worker
198*4dc78e53SAndroid Build Coastguard Worker if (!(info->ce_mask & PPP_ATTR_FD))
199*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
200*4dc78e53SAndroid Build Coastguard Worker
201*4dc78e53SAndroid Build Coastguard Worker if (fd)
202*4dc78e53SAndroid Build Coastguard Worker *fd = info->pi_fd;
203*4dc78e53SAndroid Build Coastguard Worker
204*4dc78e53SAndroid Build Coastguard Worker return 0;
205*4dc78e53SAndroid Build Coastguard Worker }
206*4dc78e53SAndroid Build Coastguard Worker
207*4dc78e53SAndroid Build Coastguard Worker /** @} */
208*4dc78e53SAndroid Build Coastguard Worker
ppp_init(void)209*4dc78e53SAndroid Build Coastguard Worker static void _nl_init ppp_init(void)
210*4dc78e53SAndroid Build Coastguard Worker {
211*4dc78e53SAndroid Build Coastguard Worker rtnl_link_register_info(&ppp_info_ops);
212*4dc78e53SAndroid Build Coastguard Worker }
213*4dc78e53SAndroid Build Coastguard Worker
ppp_exit(void)214*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit ppp_exit(void)
215*4dc78e53SAndroid Build Coastguard Worker {
216*4dc78e53SAndroid Build Coastguard Worker rtnl_link_unregister_info(&ppp_info_ops);
217*4dc78e53SAndroid Build Coastguard Worker }
218*4dc78e53SAndroid Build Coastguard Worker
219*4dc78e53SAndroid Build Coastguard Worker /** @} */
220