option proto static
option ipaddr 192.168.1.1
option netmask 255.255.255.0
+ option gateway 192.168.1.2
interface_del_address(iface, addr);
}
}
+
+int interface_add_route(struct interface *iface, struct device_route *route)
+{
+ list_add(&route->list, &iface->routes);
+ return system_add_route(iface->l3_iface->dev, route);
+}
+
+void interface_del_route(struct interface *iface, struct device_route *route)
+{
+ list_del(&route->list);
+ system_del_route(iface->l3_iface->dev, route);
+}
+
+void interface_del_all_routes(struct interface *iface)
+{
+ struct device_route *route, *tmp;
+
+ list_for_each_entry_safe(route, tmp, &iface->routes, list)
+ interface_del_route(iface, route);
+}
iface->state = IFS_TEARDOWN;
interface_event(iface, IFEV_DOWN);
+ interface_del_all_routes(iface);
interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, force);
}
void interface_del_address(struct interface *iface, struct device_addr *addr);
void interface_del_ctx_addr(struct interface *iface, void *ctx);
+int interface_add_route(struct interface *iface, struct device_route *route);
+void interface_del_route(struct interface *iface, struct device_route *route);
+void interface_del_all_routes(struct interface *iface);
+
void start_pending_interfaces(void);
#endif
return n_addr;
}
+static bool
+parse_gateway_option(struct static_proto_state *state, struct uci_option *o, bool v6)
+{
+ struct device_route *route;
+ const char *str = o->v.string;
+ int af = v6 ? AF_INET6 : AF_INET;
+
+ route = calloc(1, sizeof(*route));
+ if (!inet_pton(af, str, &route->nexthop)) {
+ interface_add_error(state->iface, "proto-static",
+ "INVALID_GATEWAY", &str, 1);
+ free(route);
+ return false;
+ }
+ route->mask = 0;
+ route->flags = DEVADDR_DEVICE | (v6 ? DEVADDR_INET6 : DEVADDR_INET4);
+ interface_add_route(state->iface, route);
+
+ return true;
+}
+
enum {
OPT_IPADDR,
OPT_IP6ADDR,
if (n_v4 < 0 || n_v6 < 0)
goto out;
-#if 0
- if (ps.n_v4 && tb[OPT_GATEWAY]) {
- if (!inet_pton(AF_INET, tb[OPT_GATEWAY]->v.string, &ps.ipv4gw)) {
- error = "INVALID_GATEWAY";
- goto error;
- }
- ps.flags |= STATIC_F_IPV4GW;
+ if (n_v4 && tb[OPT_GATEWAY]) {
+ if (!parse_gateway_option(state, tb[OPT_GATEWAY], false))
+ goto out;
}
- if (ps.n_v6 && tb[OPT_IP6GW]) {
- if (!inet_pton(AF_INET6, tb[OPT_IP6GW]->v.string, &ps.ipv6gw)) {
- error = "INVALID_GATEWAY";
- goto error;
- }
- ps.flags |= STATIC_F_IPV6GW;
+ if (n_v6 && tb[OPT_IP6GW]) {
+ if (!parse_gateway_option(state, tb[OPT_IP6GW], true))
+ goto out;
}
-#endif
return true;
return 0;
}
+
+int system_add_route(struct device *dev, struct device_route *route)
+{
+ uint8_t *a1 = (uint8_t *) &route->addr.in;
+ uint8_t *a2 = (uint8_t *) &route->nexthop.in;
+ char addr[40], gw[40] = "", devstr[64] = "";
+
+ if ((route->flags & DEVADDR_FAMILY) != DEVADDR_INET4)
+ return -1;
+
+ if (!route->mask)
+ sprintf(addr, "default");
+ else
+ sprintf(addr, "%d.%d.%d.%d/%d",
+ a1[0], a1[1], a1[2], a1[3], route->mask);
+
+ if (memcmp(a2, "\x00\x00\x00\x00", 4) != 0)
+ sprintf(gw, " gw %d.%d.%d.%d",
+ a2[0], a2[1], a2[2], a2[3]);
+
+ if (route->flags & DEVADDR_DEVICE)
+ sprintf(devstr, " dev %s", dev->ifname);
+
+ DPRINTF("route add %s%s%s\n", addr, gw, devstr);
+ return 0;
+}
+
+int system_del_route(struct device *dev, struct device_route *route)
+{
+ uint8_t *a1 = (uint8_t *) &route->addr.in;
+ uint8_t *a2 = (uint8_t *) &route->nexthop.in;
+ char addr[40], gw[40] = "", devstr[64] = "";
+
+ if ((route->flags & DEVADDR_FAMILY) != DEVADDR_INET4)
+ return -1;
+
+ if (!route->mask)
+ sprintf(addr, "default");
+ else
+ sprintf(addr, "%d.%d.%d.%d/%d",
+ a1[0], a1[1], a1[2], a1[3], route->mask);
+
+ if (memcmp(a2, "\x00\x00\x00\x00", 4) != 0)
+ sprintf(gw, " gw %d.%d.%d.%d",
+ a2[0], a2[1], a2[2], a2[3]);
+
+ if (route->flags & DEVADDR_DEVICE)
+ sprintf(devstr, " dev %s", dev->ifname);
+
+ DPRINTF("route del %s%s%s\n", addr, gw, devstr);
+ return 0;
+}
int system_add_address(struct device *dev, struct device_addr *addr);
int system_del_address(struct device *dev, struct device_addr *addr);
+int system_add_route(struct device *dev, struct device_route *route);
+int system_del_route(struct device *dev, struct device_route *route);
+
#endif