00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #include <netlink-local.h>
00061 #include <netlink/netlink.h>
00062 #include <netlink/attr.h>
00063 #include <netlink/route/rtnl.h>
00064 #include <netlink/route/link/api.h>
00065
00066
00067 struct inet_data
00068 {
00069 uint8_t i_confset[IPV4_DEVCONF_MAX];
00070 uint32_t i_conf[IPV4_DEVCONF_MAX];
00071 };
00072
00073
00074 static void *inet_alloc(struct rtnl_link *link)
00075 {
00076 return calloc(1, sizeof(struct inet_data));
00077 }
00078
00079 static void *inet_clone(struct rtnl_link *link, void *data)
00080 {
00081 struct inet_data *id;
00082
00083 if ((id = inet_alloc(link)))
00084 memcpy(id, data, sizeof(*id));
00085
00086 return id;
00087 }
00088
00089 static void inet_free(struct rtnl_link *link, void *data)
00090 {
00091 free(data);
00092 }
00093
00094 static struct nla_policy inet_policy[IFLA_INET6_MAX+1] = {
00095 [IFLA_INET_CONF] = { .minlen = IPV4_DEVCONF_MAX * 4 },
00096 };
00097
00098 static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data)
00099 {
00100 struct inet_data *id = data;
00101 struct nlattr *tb[IFLA_INET_MAX+1];
00102 int err;
00103
00104 err = nla_parse_nested(tb, IFLA_INET_MAX, attr, inet_policy);
00105 if (err < 0)
00106 return err;
00107
00108 if (tb[IFLA_INET_CONF])
00109 nla_memcpy(&id->i_conf, tb[IFLA_INET_CONF], sizeof(id->i_conf));
00110
00111 return 0;
00112 }
00113
00114 static int inet_fill_af(struct rtnl_link *link, struct nl_msg *msg, void *data)
00115 {
00116 struct inet_data *id = data;
00117 struct nlattr *nla;
00118 int i;
00119
00120 if (!(nla = nla_nest_start(msg, IFLA_INET_CONF)))
00121 return -NLE_MSGSIZE;
00122
00123 for (i = 0; i < IPV4_DEVCONF_MAX; i++)
00124 if (id->i_confset[i])
00125 NLA_PUT_U32(msg, i+1, id->i_conf[i]);
00126
00127 nla_nest_end(msg, nla);
00128
00129 return 0;
00130
00131 nla_put_failure:
00132 return -NLE_MSGSIZE;
00133 }
00134
00135 static const struct trans_tbl inet_devconf[] = {
00136 __ADD(IPV4_DEVCONF_FORWARDING, forwarding)
00137 __ADD(IPV4_DEVCONF_MC_FORWARDING, mc_forwarding)
00138 __ADD(IPV4_DEVCONF_PROXY_ARP, proxy_arp)
00139 __ADD(IPV4_DEVCONF_ACCEPT_REDIRECTS, accept_redirects)
00140 __ADD(IPV4_DEVCONF_SECURE_REDIRECTS, secure_redirects)
00141 __ADD(IPV4_DEVCONF_SEND_REDIRECTS, send_redirects)
00142 __ADD(IPV4_DEVCONF_SHARED_MEDIA, shared_media)
00143 __ADD(IPV4_DEVCONF_RP_FILTER, rp_filter)
00144 __ADD(IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE, accept_source_route)
00145 __ADD(IPV4_DEVCONF_BOOTP_RELAY, bootp_relay)
00146 __ADD(IPV4_DEVCONF_LOG_MARTIANS, log_martians)
00147 __ADD(IPV4_DEVCONF_TAG, tag)
00148 __ADD(IPV4_DEVCONF_ARPFILTER, arpfilter)
00149 __ADD(IPV4_DEVCONF_MEDIUM_ID, medium_id)
00150 __ADD(IPV4_DEVCONF_NOXFRM, noxfrm)
00151 __ADD(IPV4_DEVCONF_NOPOLICY, nopolicy)
00152 __ADD(IPV4_DEVCONF_FORCE_IGMP_VERSION, force_igmp_version)
00153 __ADD(IPV4_DEVCONF_ARP_ANNOUNCE, arp_announce)
00154 __ADD(IPV4_DEVCONF_ARP_IGNORE, arp_ignore)
00155 __ADD(IPV4_DEVCONF_PROMOTE_SECONDARIES, promote_secondaries)
00156 __ADD(IPV4_DEVCONF_ARP_ACCEPT, arp_accept)
00157 __ADD(IPV4_DEVCONF_ARP_NOTIFY, arp_notify)
00158 __ADD(IPV4_DEVCONF_ACCEPT_LOCAL, accept_local)
00159 __ADD(IPV4_DEVCONF_SRC_VMARK, src_vmark)
00160 __ADD(IPV4_DEVCONF_PROXY_ARP_PVLAN, proxy_arp_pvlan)
00161 };
00162
00163 const char *rtnl_link_inet_devconf2str(int type, char *buf, size_t len)
00164 {
00165 return __type2str(type, buf, len, inet_devconf,
00166 ARRAY_SIZE(inet_devconf));
00167 }
00168
00169 unsigned int rtnl_link_inet_str2devconf(const char *name)
00170 {
00171 return __str2type(name, inet_devconf, ARRAY_SIZE(inet_devconf));
00172 }
00173
00174 static void inet_dump_details(struct rtnl_link *link,
00175 struct nl_dump_params *p, void *data)
00176 {
00177 struct inet_data *id = data;
00178 char buf[64];
00179 int i, n = 0;
00180
00181 nl_dump_line(p, " ipv4 devconf:\n");
00182 nl_dump_line(p, " ");
00183
00184 for (i = 0; i < IPV4_DEVCONF_MAX; i++) {
00185 nl_dump_line(p, "%-19s %3u",
00186 rtnl_link_inet_devconf2str(i+1, buf, sizeof(buf)),
00187 id->i_conf[i]);
00188
00189 if (++n == 3) {
00190 nl_dump(p, "\n");
00191 nl_dump_line(p, " ");
00192 n = 0;
00193 } else
00194 nl_dump(p, " ");
00195 }
00196
00197 if (n != 0)
00198 nl_dump(p, "\n");
00199 }
00200
00201 static struct rtnl_link_af_ops inet_ops = {
00202 .ao_family = AF_INET,
00203 .ao_alloc = &inet_alloc,
00204 .ao_clone = &inet_clone,
00205 .ao_free = &inet_free,
00206 .ao_parse_af = &inet_parse_af,
00207 .ao_fill_af = &inet_fill_af,
00208 .ao_dump[NL_DUMP_DETAILS] = &inet_dump_details,
00209 };
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 int rtnl_link_inet_get_conf(struct rtnl_link *link, const unsigned int cfgid,
00225 uint32_t *res)
00226 {
00227 struct inet_data *id;
00228
00229 if (cfgid == 0 || cfgid > IPV4_DEVCONF_MAX)
00230 return -NLE_RANGE;
00231
00232 if (!(id = rtnl_link_af_alloc(link, &inet_ops)))
00233 return -NLE_NOATTR;
00234
00235 *res = id->i_conf[cfgid - 1];
00236
00237 return 0;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 int rtnl_link_inet_set_conf(struct rtnl_link *link, const unsigned int cfgid,
00253 uint32_t value)
00254 {
00255 struct inet_data *id;
00256
00257 if (!(id = rtnl_link_af_alloc(link, &inet_ops)))
00258 return -NLE_NOMEM;
00259
00260 if (cfgid == 0 || cfgid > IPV4_DEVCONF_MAX)
00261 return -NLE_RANGE;
00262
00263 id->i_confset[cfgid - 1] = 1;
00264 id->i_conf[cfgid - 1] = value;
00265
00266 return 0;
00267 }
00268
00269
00270 static void __init inet_init(void)
00271 {
00272 rtnl_link_af_register(&inet_ops);
00273 }
00274
00275 static void __exit inet_exit(void)
00276 {
00277 rtnl_link_af_unregister(&inet_ops);
00278 }
00279
00280