static DECL_CMD_FUNC2(setvxlan_port_range, arg1, arg2) { struct ifvxlancmd cmd; u_long min, max; if (get_val(arg1, &min) < 0 || min >= UINT16_MAX) errx(1, "invalid port range minimum: %s", arg1); if (get_val(arg2, &max) < 0 || max >= UINT16_MAX) errx(1, "invalid port range maximum: %s", arg2); if (max < min) errx(1, "invalid port range"); if (!vxlan_exists(s)) { params.vxlp_with |= VXLAN_PARAM_WITH_PORT_RANGE; params.vxlp_min_port = min; params.vxlp_max_port = max; return; } bzero(&cmd, sizeof(cmd)); cmd.vxlcmd_port_min = min; cmd.vxlcmd_port_max = max; if (do_cmd(s, VXLAN_CMD_SET_PORT_RANGE, &cmd, sizeof(cmd), 1) < 0) err(1, "VXLAN_CMD_SET_PORT_RANGE"); }
void shutdown_vxlan() { red_log(REDD_DEBUG, "Shutting down VXLAN"); if (vxlan_exists() == 0) { char *add_link_cmd[] = {"ip", "link", "del", server.vxlan_name, 0}; if (run_cmd(add_link_cmd) != 0) { red_log(REDD_WARNING, "Failed to remove link %s", server.vxlan_name); } } }
int init_vxlan() { /* * Run the following: * ip link add vxlan0 type vxlan id 1 group 239.0.0.1 dev eth0 * ip link set vxlan0 up */ int retry; int success = -1; if (vxlan_exists() != 0) { char *add_link_cmd[] = {"ip", "link", "add", server.vxlan_name, "type", "vxlan", "id", server.vxlan_vni, "dev", server.vxlan_interface, 0}; for (retry = 0; retry < server.vxlan_max_retries; retry++) { if ((success = run_cmd(add_link_cmd)) == 0) { break; } else { red_log(REDD_WARNING, "Failed to create link %s", server.vxlan_name); sleep(1); red_log(REDD_WARNING, "Retrying to create link %s", server.vxlan_name); } } } if (success == -1) return -1; char *set_link_cmd[] = {"ip", "link", "set", server.vxlan_name, "up", 0}; for (retry = 0; retry < server.vxlan_max_retries; retry++) { if ((success = run_cmd(set_link_cmd)) == 0) { break; } else { red_log(REDD_WARNING, "Failed to set link %s up", server.vxlan_name); sleep(1); red_log(REDD_WARNING, "Retrying to set link %s up", server.vxlan_name); } } if (success == -1) return -1; char *set_route_cmd[] = {"bridge", "fdb", "add", "to", "00:00:00:00:00:00", "dst", server.vxlan_group, "via", server.tun_name, "dev", server.vxlan_name, 0}; for (retry = 0; retry < server.vxlan_max_retries; retry++) { if ((success = run_cmd(set_route_cmd)) == 0) { break; } else { red_log(REDD_WARNING, "Failed to set route %s", server.vxlan_name); sleep(1); red_log(REDD_WARNING, "Retrying to set route %s", server.vxlan_name); } } return success; }
static DECL_CMD_FUNC(setvxlan_learn, arg, d) { struct ifvxlancmd cmd; if (!vxlan_exists(s)) { params.vxlp_with |= VXLAN_PARAM_WITH_LEARN; params.vxlp_learn = d; return; } bzero(&cmd, sizeof(cmd)); if (d != 0) cmd.vxlcmd_flags |= VXLAN_CMD_FLAG_LEARN; if (do_cmd(s, VXLAN_CMD_SET_LEARN, &cmd, sizeof(cmd), 1) < 0) err(1, "VXLAN_CMD_SET_LEARN"); }
static DECL_CMD_FUNC(setvxlan_dev, arg, d) { struct ifvxlancmd cmd; if (!vxlan_exists(s)) { params.vxlp_with |= VXLAN_PARAM_WITH_MULTICAST_IF; strlcpy(params.vxlp_mc_ifname, arg, sizeof(params.vxlp_mc_ifname)); return; } bzero(&cmd, sizeof(cmd)); strlcpy(cmd.vxlcmd_ifname, arg, sizeof(cmd.vxlcmd_ifname)); if (do_cmd(s, VXLAN_CMD_SET_MULTICAST_IF, &cmd, sizeof(cmd), 1) < 0) err(1, "VXLAN_CMD_SET_MULTICAST_IF"); }
static DECL_CMD_FUNC(setvxlan_ttl, arg, d) { struct ifvxlancmd cmd; u_long val; if (get_val(arg, &val) < 0 || val > 256) errx(1, "invalid TTL value: %s", arg); if (!vxlan_exists(s)) { params.vxlp_with |= VXLAN_PARAM_WITH_TTL; params.vxlp_ttl = val; return; } bzero(&cmd, sizeof(cmd)); cmd.vxlcmd_ttl = val; if (do_cmd(s, VXLAN_CMD_SET_TTL, &cmd, sizeof(cmd), 1) < 0) err(1, "VXLAN_CMD_SET_TTL"); }
static DECL_CMD_FUNC(setvxlan_maxaddr, arg, d) { struct ifvxlancmd cmd; u_long val; if (get_val(arg, &val) < 0 || (val & ~0xFFFFFFFF) != 0) errx(1, "invalid maxaddr value: %s", arg); if (!vxlan_exists(s)) { params.vxlp_with |= VXLAN_PARAM_WITH_FTABLE_MAX; params.vxlp_ftable_max = val & 0xFFFFFFFF; return; } bzero(&cmd, sizeof(cmd)); cmd.vxlcmd_ftable_max = val & 0xFFFFFFFF; if (do_cmd(s, VXLAN_CMD_SET_FTABLE_MAX, &cmd, sizeof(cmd), 1) < 0) err(1, "VXLAN_CMD_SET_FTABLE_MAX"); }
static DECL_CMD_FUNC(setvxlan_remote_port, arg, d) { struct ifvxlancmd cmd; u_long val; if (get_val(arg, &val) < 0 || val >= UINT16_MAX) errx(1, "invalid remote port: %s", arg); if (!vxlan_exists(s)) { params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_PORT; params.vxlp_remote_port = val; return; } bzero(&cmd, sizeof(cmd)); cmd.vxlcmd_port = val; if (do_cmd(s, VXLAN_CMD_SET_REMOTE_PORT, &cmd, sizeof(cmd), 1) < 0) err(1, "VXLAN_CMD_SET_REMOTE_PORT"); }
static DECL_CMD_FUNC(setvxlan_vni, arg, d) { struct ifvxlancmd cmd; u_long val; if (get_val(arg, &val) < 0 || val >= VXLAN_VNI_MAX) errx(1, "invalid network identifier: %s", arg); if (!vxlan_exists(s)) { params.vxlp_with |= VXLAN_PARAM_WITH_VNI; params.vxlp_vni = val; return; } bzero(&cmd, sizeof(cmd)); cmd.vxlcmd_vni = val; if (do_cmd(s, VXLAN_CMD_SET_VNI, &cmd, sizeof(cmd), 1) < 0) err(1, "VXLAN_CMD_SET_VNI"); }
static DECL_CMD_FUNC(setvxlan_group, addr, d) { struct ifvxlancmd cmd; struct addrinfo *ai; struct sockaddr *sa; int error; bzero(&cmd, sizeof(cmd)); if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0) errx(1, "error in parsing group address string: %s", gai_strerror(error)); sa = ai->ai_addr; switch (ai->ai_family) { #ifdef INET case AF_INET: { struct in_addr addr = ((struct sockaddr_in *)sa)->sin_addr; if (!IN_MULTICAST(ntohl(addr.s_addr))) errx(1, "group address must be multicast"); cmd.vxlcmd_sa.in4.sin_family = AF_INET; cmd.vxlcmd_sa.in4.sin_addr = addr; break; } #endif #ifdef INET6 case AF_INET6: { struct in6_addr *addr = &((struct sockaddr_in6 *)sa)->sin6_addr; if (!IN6_IS_ADDR_MULTICAST(addr)) errx(1, "group address must be multicast"); cmd.vxlcmd_sa.in6.sin6_family = AF_INET6; cmd.vxlcmd_sa.in6.sin6_addr = *addr; break; } #endif default: errx(1, "group address %s not supported", addr); } freeaddrinfo(ai); if (!vxlan_exists(s)) { if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) { params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR4; params.vxlp_remote_in4 = cmd.vxlcmd_sa.in4.sin_addr; } else { params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR6; params.vxlp_remote_in6 = cmd.vxlcmd_sa.in6.sin6_addr; } return; } if (do_cmd(s, VXLAN_CMD_SET_REMOTE_ADDR, &cmd, sizeof(cmd), 1) < 0) err(1, "VXLAN_CMD_SET_REMOTE_ADDR"); }