mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 17:42:41 +00:00
WIFI-4201: Add provision to set the AP LAN Ports to Bridge/NAT
1. Add provision to tag with vlan when set to Bridge mode (br-wan). 2. Add provision to set the local IP address in NAT (br-lan) 3. Display the Ethernet port status(up/down) and negotiated rate. 4. Add provision to set lan eth port to bridge/nat. Signed-off-by: Chaitanya Godavarthi <chaitanya.kiran@netexperience.com>
This commit is contained in:
committed by
Arif Alam
parent
16149f6ba5
commit
98104a2e8d
@@ -1,6 +1,21 @@
|
||||
#!/bin/sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
if="$(uci get network.wan.ifname)"
|
||||
json_init
|
||||
json_load "$(cat /etc/board.json)"
|
||||
json_select network
|
||||
json_select "wan"
|
||||
json_get_vars ifname
|
||||
json_select ..
|
||||
json_select ..
|
||||
|
||||
[ -n "$ifname" ] || {
|
||||
ifname=$(uci get network.wan.ifname)
|
||||
ifname=${ifname%% *}
|
||||
}
|
||||
|
||||
|
||||
if="$ifname"
|
||||
[ "$(cat /sys/class/net/"${if}"/carrier)" = 0 ] && {
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
[ "$ACTION" = "add" ] || exit 0
|
||||
|
||||
json_init
|
||||
json_load "$(cat /etc/board.json)"
|
||||
json_select network
|
||||
json_select "wan"
|
||||
json_get_vars ifname
|
||||
json_select ..
|
||||
json_select ..
|
||||
|
||||
[ -n "$ifname" ] || {
|
||||
ifname=$(uci get network.wan.ifname)
|
||||
ifname=${ifname%% *}
|
||||
}
|
||||
|
||||
net=$(uci get wireless.${DEVICENAME}.network)
|
||||
vid=$(uci get wireless.${DEVICENAME}.vid)
|
||||
|
||||
@@ -9,6 +23,6 @@ vid=$(uci get wireless.${DEVICENAME}.vid)
|
||||
|
||||
bridge vlan add vid $vid dev br-lan self
|
||||
bridge vlan add vid $vid dev br-wan self
|
||||
bridge vlan add vid $vid dev $(uci get network.wan.ifname)
|
||||
bridge vlan add vid $vid dev $ifname
|
||||
bridge vlan add pvid $vid vid $vid dev ${DEVICENAME} untagged
|
||||
exit 0
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
#!/bin/sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
[ "$ACTION" = "add" ] || exit 0
|
||||
|
||||
json_init
|
||||
json_load "$(cat /etc/board.json)"
|
||||
json_select network
|
||||
json_select "wan"
|
||||
json_get_vars ifname
|
||||
json_select ..
|
||||
json_select ..
|
||||
|
||||
[ -n "$ifname" ] || {
|
||||
ifname=$(uci get network.wan.ifname)
|
||||
ifname=${ifname%% *}
|
||||
}
|
||||
|
||||
dvid=`echo $DEVICENAME | awk -F "." '{ printf $2 }'`
|
||||
[ -z "$dvid" -o "$dvid" = 0 -o "$dvid" = 1 ] && exit 0
|
||||
|
||||
@@ -13,7 +28,7 @@ brctl delif br-wan.$dvid $DEVICENAME
|
||||
brctl addif br-wan $DEVICENAME
|
||||
|
||||
bridge vlan add vid $dvid dev br-wan self
|
||||
bridge vlan add vid $dvid dev $(uci get network.wan.ifname)
|
||||
bridge vlan add vid $dvid dev $ifname
|
||||
bridge vlan add pvid $dvid vid $dvid dev $DEVICENAME untagged
|
||||
bridge vlan add vid $dvid dev br-lan self
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
Index: opensync-2.0.5.0/interfaces/opensync.ovsschema
|
||||
===================================================================
|
||||
--- opensync-2.0.5.0.orig/interfaces/opensync.ovsschema
|
||||
+++ opensync-2.0.5.0/interfaces/opensync.ovsschema
|
||||
@@ -900,6 +900,17 @@
|
||||
"min": 0,
|
||||
"max": 64
|
||||
}
|
||||
+ },
|
||||
+ "eth_ports": {
|
||||
+ "type": {
|
||||
+ "key": {
|
||||
+ "type": "string",
|
||||
+ "minLength": 1,
|
||||
+ "maxLength": 32
|
||||
+ },
|
||||
+ "min": 0,
|
||||
+ "max": 1
|
||||
+ }
|
||||
}
|
||||
},
|
||||
"isRoot": true,
|
||||
@@ -1170,6 +1181,22 @@
|
||||
"min": 0,
|
||||
"max": 64
|
||||
}
|
||||
+ },
|
||||
+ "eth_ports": {
|
||||
+ "type": {
|
||||
+ "key": {
|
||||
+ "type": "string",
|
||||
+ "minLength": 1,
|
||||
+ "maxLength": 32
|
||||
+ },
|
||||
+ "value": {
|
||||
+ "type": "string",
|
||||
+ "minLength": 1,
|
||||
+ "maxLength": 64
|
||||
+ },
|
||||
+ "min": 0,
|
||||
+ "max": 32
|
||||
+ }
|
||||
}
|
||||
},
|
||||
"isRoot": true,
|
||||
@@ -90,6 +90,24 @@ const char mesh_options_table[SCHEMA_MESH_OPTS_MAX][SCHEMA_MESH_OPT_SZ] =
|
||||
SCHEMA_CONSTS_MESH_HOP_PENALTY,
|
||||
};
|
||||
|
||||
|
||||
char* get_eth_map_info(char* iface);
|
||||
static void init_eth_ports_config(struct schema_Wifi_Inet_Config *config)
|
||||
{
|
||||
char *wan = NULL;
|
||||
char *lan = NULL;
|
||||
|
||||
wan = get_eth_map_info("wan");
|
||||
if (!strncmp(config->if_name, "wan", 3)) {
|
||||
SCHEMA_SET_STR(config->eth_ports, wan);
|
||||
}
|
||||
|
||||
lan = get_eth_map_info("lan");
|
||||
if (!strncmp(config->if_name, "lan", 3)) {
|
||||
SCHEMA_SET_STR(config->eth_ports, lan);
|
||||
}
|
||||
}
|
||||
|
||||
static void wifi_inet_conf_load(struct uci_section *s)
|
||||
{
|
||||
struct blob_attr *tb[__NET_ATTR_MAX] = { };
|
||||
@@ -190,6 +208,7 @@ static void wifi_inet_conf_load(struct uci_section *s)
|
||||
}
|
||||
}
|
||||
|
||||
init_eth_ports_config(&conf);
|
||||
firewall_get_config(&conf);
|
||||
|
||||
if (!ovsdb_table_upsert(&table_Wifi_Inet_Config, &conf, false))
|
||||
@@ -261,8 +280,9 @@ static int wifi_inet_conf_add(struct schema_Wifi_Inet_Config *iconf)
|
||||
snprintf(uci_ifname, sizeof(uci_ifname), "gre4t-%s.%d", iconf->parent_ifname, iconf->vlan_id);
|
||||
blobmsg_add_string(&b, "ifname", uci_ifname);
|
||||
blobmsg_add_string(&b, "type", "bridge");
|
||||
}
|
||||
else {
|
||||
} else if(!strncmp(iconf->parent_ifname, "eth", strlen("eth"))) {
|
||||
blobmsg_add_string(&b, "ifname", iconf->parent_ifname);
|
||||
} else {
|
||||
snprintf(uci_ifname, sizeof(uci_ifname), "br-%s.%d", iconf->parent_ifname, iconf->vlan_id);
|
||||
blobmsg_add_string(&b, "ifname", uci_ifname);
|
||||
}
|
||||
@@ -345,6 +365,101 @@ static int wifi_inet_conf_add(struct schema_Wifi_Inet_Config *iconf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_inet_dup_conf_single(struct blob_buf *dup, char *if_name, int exclude)
|
||||
|
||||
{
|
||||
struct blob_attr *tb[__NET_ATTR_MAX] = { };
|
||||
struct uci_package *network = NULL;
|
||||
struct uci_section *s;
|
||||
int i = 0;
|
||||
|
||||
/* Load the network uci and lookup the if_name section */
|
||||
uci_load(uci, "network", &network);
|
||||
s = uci_lookup_section(uci, network , if_name);
|
||||
|
||||
if(!s) {
|
||||
LOG(ERR, " %s: Failed to load uci", __func__);
|
||||
uci_unload(uci, network);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy the uci section to blob and parse it */
|
||||
blob_buf_init(&b, 0);
|
||||
uci_to_blob(&b, s, &network_param);
|
||||
uci_unload(uci, network);
|
||||
blobmsg_parse(network_policy, __NET_ATTR_MAX,
|
||||
tb, blob_data(b.head),
|
||||
blob_len(b.head));
|
||||
|
||||
blob_buf_init(dup, 0);
|
||||
blob_buf_init(&del, 0);
|
||||
|
||||
/* copy the parsed data to the passed blob buffer */
|
||||
for (i = 0; i < __NET_ATTR_MAX; i++) {
|
||||
if (i == exclude)
|
||||
continue;
|
||||
if (tb[i]) {
|
||||
switch (network_policy[i].type) {
|
||||
case BLOBMSG_TYPE_STRING:
|
||||
blobmsg_add_string(dup, network_policy[i].name,
|
||||
blobmsg_get_string(tb[i]));
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT32:
|
||||
blobmsg_add_u32(dup, network_policy[i].name,
|
||||
blobmsg_get_u32(tb[i]));
|
||||
break;
|
||||
case BLOBMSG_TYPE_BOOL:
|
||||
blobmsg_add_bool(dup, network_policy[i].name,
|
||||
blobmsg_get_bool(tb[i]));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_inet_conf_modify(struct schema_Wifi_Inet_Config *iconf)
|
||||
{
|
||||
struct blob_buf dup = { };
|
||||
|
||||
if (iconf->eth_ports_changed) {
|
||||
LOGI("%s+%d: changed=%d if_name=%s, eth_ports=%s",
|
||||
__func__, __LINE__, iconf->eth_ports_changed,
|
||||
iconf->if_name, iconf->eth_ports);
|
||||
|
||||
iconf->eth_ports_changed = 0;
|
||||
|
||||
/* Copy the current uci interface section to the blob excluding
|
||||
* the passed NET_ATTR (changed config attribute) */
|
||||
if (wifi_inet_dup_conf_single(&dup, iconf->if_name,
|
||||
NET_ATTR_IFNAME) != 0)
|
||||
return -1;
|
||||
|
||||
/* Add the changed configuration to the blob */
|
||||
blobmsg_add_string(&dup, "ifname", iconf->eth_ports);
|
||||
|
||||
/* Delete the current uci interface section */
|
||||
if (uci_section_del(uci, "network", "network",
|
||||
iconf->if_name, "interface") != 0)
|
||||
return -1;
|
||||
|
||||
/* Add the resulting modified blob to uci */
|
||||
if (blob_to_uci_section(uci, "network",
|
||||
iconf->if_name,
|
||||
"interface", dup.head,
|
||||
&network_param,
|
||||
del.head) != 0)
|
||||
return -1;
|
||||
|
||||
uci_commit_all(uci);
|
||||
blob_buf_free(&dup);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wifi_inet_conf_del(struct schema_Wifi_Inet_Config *iconf)
|
||||
{
|
||||
if (!strcmp(iconf->if_name, "wan") || !strcmp(iconf->if_name, "lan")) {
|
||||
@@ -386,6 +501,13 @@ static void callback_Wifi_Inet_Config(ovsdb_update_monitor_t *mon,
|
||||
}
|
||||
|
||||
wifi_inet_conf_add(iconf);
|
||||
system("cp /etc/config/network /tmp/bkp-network");
|
||||
if (wifi_inet_conf_modify(iconf) != 0) {
|
||||
LOG(ERR, "Failed to modify network Conf restoring old conf");
|
||||
system("cp /tmp/bkp-network /etc/config/network");
|
||||
}
|
||||
system("rm /tmp/bkp-network");
|
||||
|
||||
netifd_modify_inet_conf(iconf);
|
||||
break;
|
||||
case OVSDB_UPDATE_DEL:
|
||||
@@ -413,10 +535,12 @@ void wifi_inet_config_init(void)
|
||||
uci_foreach_element(&network->sections, e) {
|
||||
struct uci_section *s = uci_to_section(e);
|
||||
|
||||
if (!strcmp(s->type, "interface"))
|
||||
if (!strcmp(s->type, "interface")) {
|
||||
wifi_inet_conf_load(s);
|
||||
}
|
||||
}
|
||||
uci_unload(uci, network);
|
||||
|
||||
OVSDB_TABLE_MONITOR(Wifi_Inet_Config, false);
|
||||
|
||||
return;
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <libubox/blobmsg_json.h>
|
||||
|
||||
enum {
|
||||
NET_ATTR_INTERFACE,
|
||||
@@ -100,6 +103,259 @@ int l3_device_split(char *l3_device, struct iface_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool wifi_inet_state_del(const char *ifname);
|
||||
bool wifi_inet_master_del(const char *ifname);
|
||||
#define DOT_OR_DOTDOT(s) ((s)[0] == '.' && (!(s)[1] || ((s)[1] == '.' && !(s)[2])))
|
||||
static struct blob_buf bb;
|
||||
#define DEFAULT_BOARD_JSON "/etc/board.json"
|
||||
#define MAX_ETH_PORTS 5
|
||||
static struct blob_attr *board_info;
|
||||
|
||||
struct eth_port_state {
|
||||
char ifname[8];
|
||||
char state[8];
|
||||
char speed[8];
|
||||
char duplex[16];
|
||||
char bridge[8];
|
||||
};
|
||||
|
||||
static struct eth_port_state wanport;
|
||||
static struct eth_port_state lanport[MAX_ETH_PORTS];
|
||||
|
||||
static struct blob_attr* config_find_blobmsg_attr(struct blob_attr *attr, const char *name, int type)
|
||||
{
|
||||
struct blobmsg_policy policy = { .name = name, .type = type };
|
||||
struct blob_attr *cur;
|
||||
|
||||
blobmsg_parse(&policy, 1, &cur, blobmsg_data(attr), blobmsg_len(attr));
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
|
||||
char* get_eth_map_info(char* iface)
|
||||
{
|
||||
struct blob_attr *cur;
|
||||
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
if (!blobmsg_add_json_from_file(&bb, DEFAULT_BOARD_JSON)) {
|
||||
return NULL;
|
||||
}
|
||||
if (board_info != NULL) {
|
||||
free(board_info);
|
||||
board_info = NULL;
|
||||
}
|
||||
cur = config_find_blobmsg_attr(bb.head, "network", BLOBMSG_TYPE_TABLE);
|
||||
if (!cur) {
|
||||
LOGD("Failed to find network in board.json file");
|
||||
return NULL;
|
||||
}
|
||||
board_info = blob_memdup(cur);
|
||||
if (!board_info)
|
||||
return NULL;
|
||||
|
||||
cur = config_find_blobmsg_attr(board_info, iface, BLOBMSG_TYPE_TABLE);
|
||||
if (!cur) {
|
||||
LOGD("Failed to find %s in board.json file", iface);
|
||||
return NULL;
|
||||
}
|
||||
cur = config_find_blobmsg_attr(cur, "ifname", BLOBMSG_TYPE_STRING);
|
||||
if (!cur) {
|
||||
LOGD("Failed to find ifname in board.json file");
|
||||
return NULL;
|
||||
}
|
||||
return blobmsg_get_string(cur);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void update_eth_state (char *eth, struct eth_port_state *eth_state)
|
||||
{
|
||||
char sysfs_path[128];
|
||||
int fd = 0;
|
||||
struct dirent *ent;
|
||||
DIR *iface;
|
||||
int carrier = 1;
|
||||
ssize_t len = 0;
|
||||
|
||||
memset(eth_state, 0, sizeof(struct eth_port_state));
|
||||
/* eth interface name */
|
||||
strncpy(eth_state->ifname, eth, sizeof(eth_state->ifname));
|
||||
|
||||
/* eth interface state */
|
||||
snprintf(sysfs_path, sizeof(sysfs_path),
|
||||
"/sys/class/net/%s/carrier", eth);
|
||||
|
||||
fd = open(sysfs_path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
carrier = 0;
|
||||
close(fd);
|
||||
} else {
|
||||
len = read(fd, eth_state->state, 15);
|
||||
if (len < 0) {
|
||||
carrier = 0;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
if(!strncmp(eth_state->state, "0", 1))
|
||||
carrier = 0;
|
||||
|
||||
strncpy(eth_state->state, carrier? "up":"down", sizeof(eth_state->state));
|
||||
|
||||
/* eth interface wan bridge */
|
||||
snprintf(sysfs_path, sizeof(sysfs_path),
|
||||
"/sys/class/net/br-wan/brif");
|
||||
|
||||
iface = opendir(sysfs_path);
|
||||
if (iface) {
|
||||
while ((ent = readdir(iface)) != NULL) {
|
||||
if (DOT_OR_DOTDOT(ent->d_name))
|
||||
continue;
|
||||
if (strncmp(ent->d_name, eth_state->ifname, sizeof(eth_state->ifname)) == 0)
|
||||
strncpy(eth_state->bridge, "br-wan", sizeof(eth_state->ifname));
|
||||
}
|
||||
closedir(iface);
|
||||
}
|
||||
|
||||
/* eth interface lan bridge */
|
||||
snprintf(sysfs_path, sizeof(sysfs_path),
|
||||
"/sys/class/net/br-lan/brif");
|
||||
|
||||
iface = opendir(sysfs_path);
|
||||
if (iface) {
|
||||
while ((ent = readdir(iface)) != NULL) {
|
||||
if (DOT_OR_DOTDOT(ent->d_name))
|
||||
continue;
|
||||
if (strncmp(ent->d_name, eth_state->ifname, sizeof(eth_state->ifname)) == 0)
|
||||
strncpy(eth_state->bridge, "br-lan", sizeof(eth_state->bridge));
|
||||
}
|
||||
closedir(iface);
|
||||
}
|
||||
|
||||
/* eth interface speed Mbits/sec */
|
||||
snprintf(sysfs_path, sizeof(sysfs_path),
|
||||
"/sys/class/net/%s/speed", eth);
|
||||
|
||||
fd = open(sysfs_path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
close(fd);
|
||||
} else {
|
||||
|
||||
len = read(fd, eth_state->speed, sizeof(eth_state->speed) -1);
|
||||
|
||||
if (len < 0)
|
||||
snprintf(eth_state->speed, sizeof(eth_state->speed), "0");
|
||||
else
|
||||
eth_state->speed[len-1] = '\0';
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* eth interface duplex */
|
||||
snprintf(sysfs_path, sizeof(sysfs_path),
|
||||
"/sys/class/net/%s/duplex", eth);
|
||||
|
||||
fd = open(sysfs_path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
close(fd);
|
||||
} else {
|
||||
len = read(fd, eth_state->duplex, sizeof(eth_state->duplex) -1);
|
||||
|
||||
if (len < 0)
|
||||
snprintf(eth_state->duplex, sizeof(eth_state->duplex), "none");
|
||||
else
|
||||
eth_state->duplex[len-1] = '\0';
|
||||
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void update_eth_ports_states(struct schema_Wifi_Inet_State *state)
|
||||
{
|
||||
char *wan = NULL;
|
||||
char *lan = NULL;
|
||||
char *eth = NULL;
|
||||
int cnt = 0;
|
||||
int i = 0;
|
||||
char port_status[128] = {'\0'};
|
||||
char brname[IFNAMSIZ] = {'\0'};
|
||||
|
||||
wan = get_eth_map_info("wan");
|
||||
update_eth_state(wan, &wanport);
|
||||
|
||||
lan = get_eth_map_info("lan");
|
||||
eth = strtok (lan," ");
|
||||
for (i = 0; i < MAX_ETH_PORTS && eth != NULL; i++)
|
||||
{
|
||||
update_eth_state(eth, &lanport[i]);
|
||||
eth = strtok (NULL, " ");
|
||||
}
|
||||
|
||||
if (!strncmp(state->if_name, "wan", 3))
|
||||
strncpy(brname, "br-wan", 6);
|
||||
else if (!strncmp(state->if_name, "lan", 3))
|
||||
strncpy(brname, "br-lan", 6);
|
||||
|
||||
if (strcmp(wanport.bridge, brname) == 0) {
|
||||
STRSCPY(state->eth_ports_keys[0], wanport.ifname);
|
||||
snprintf(port_status, sizeof(port_status), "%s wan %sMbps %s",
|
||||
wanport.state, wanport.speed, wanport.duplex);
|
||||
STRSCPY(state->eth_ports[0], port_status);
|
||||
cnt++;
|
||||
state->eth_ports_len = cnt;
|
||||
}
|
||||
for (i = 0; i < MAX_ETH_PORTS && lanport[i].ifname != NULL; i++) {
|
||||
if (strcmp(lanport[i].bridge, brname) == 0) {
|
||||
STRSCPY(state->eth_ports_keys[cnt+i], lanport[i].ifname);
|
||||
memset(port_status, '\0', sizeof(port_status));
|
||||
snprintf(port_status, sizeof(port_status), "%s lan %sMbps %s",
|
||||
lanport[i].state, lanport[i].speed, lanport[i].duplex);
|
||||
|
||||
STRSCPY(state->eth_ports[cnt+i], port_status);
|
||||
cnt++;
|
||||
state->eth_ports_len = cnt;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strncmp(state->if_name, "eth", 3)) {
|
||||
|
||||
char *delim = NULL;
|
||||
char name[IFNAMSIZ] = {'\0'};
|
||||
|
||||
delim = strstr(state->if_name, "_");
|
||||
if (delim)
|
||||
strncpy(name, state->if_name, delim - state->if_name);
|
||||
|
||||
if (name[0] == '\0')
|
||||
return;
|
||||
|
||||
|
||||
if (strcmp(wanport.ifname, name) == 0) {
|
||||
STRSCPY(state->eth_ports_keys[0], wanport.ifname);
|
||||
memset(port_status, '\0', sizeof(port_status));
|
||||
snprintf(port_status, sizeof(port_status), "%s wan %sMbps %s",
|
||||
wanport.state, wanport.speed, wanport.duplex);
|
||||
STRSCPY(state->eth_ports[0], port_status);
|
||||
state->eth_ports_len = 1;
|
||||
} else {
|
||||
for (i = 0; i < MAX_ETH_PORTS && lanport[i].ifname != NULL; i++) {
|
||||
if (strcmp(lanport[i].ifname, name) == 0) {
|
||||
STRSCPY(state->eth_ports_keys[0], lanport[i].ifname);
|
||||
memset(port_status, '\0', sizeof(port_status));
|
||||
snprintf(port_status, sizeof(port_status), "%s lan %sMbps %s",
|
||||
lanport[i].state, lanport[i].speed, lanport[i].duplex);
|
||||
|
||||
STRSCPY(state->eth_ports[0], port_status);
|
||||
state->eth_ports_len = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_inet_state_set(struct blob_attr *msg)
|
||||
{
|
||||
struct blob_attr *tb[__NET_ATTR_MAX] = { };
|
||||
@@ -124,6 +380,13 @@ void wifi_inet_state_set(struct blob_attr *msg)
|
||||
state.enabled = true;
|
||||
state.network = true;
|
||||
} else {
|
||||
|
||||
/* Delete VLAN interface state column if disabled */
|
||||
if (strstr(state.if_name, "_") != NULL) {
|
||||
wifi_inet_state_del(state.if_name);
|
||||
return;
|
||||
}
|
||||
|
||||
state.enabled = false;
|
||||
state.network = false;
|
||||
}
|
||||
@@ -143,6 +406,23 @@ void wifi_inet_state_set(struct blob_attr *msg)
|
||||
else if (!strncmp(l3_device, "gre4", strlen("gre4")) ||
|
||||
!strncmp(l3_device, "gre6", strlen("gre6")))
|
||||
SCHEMA_SET_STR(state.if_type, "gre");
|
||||
/* Fill if_type, vlan_id and parent_ifname using
|
||||
* if_name (eg:eth0_100) */
|
||||
else if (!strncmp(l3_device, "eth", strlen("eth"))) {
|
||||
char *delim = NULL;
|
||||
delim = strstr(state.if_name, "_");
|
||||
if (delim) {
|
||||
struct iface_info info;
|
||||
memset (&info, 0, sizeof(info));
|
||||
SCHEMA_SET_STR(state.if_type, "vlan");
|
||||
strncpy(info.name, &l3_device[0],
|
||||
delim - state.if_name);
|
||||
SCHEMA_SET_STR(state.parent_ifname, info.name);
|
||||
info.vid = atoi(&delim[1]);
|
||||
SCHEMA_SET_INT(state.vlan_id, info.vid);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
SCHEMA_SET_STR(state.if_type, "eth");
|
||||
if (!l3_device_split(l3_device, &info) && strcmp(info.name, state.if_name)) {
|
||||
@@ -262,6 +542,8 @@ void wifi_inet_state_set(struct blob_attr *msg)
|
||||
}
|
||||
}
|
||||
|
||||
update_eth_ports_states(&state);
|
||||
|
||||
if (!ovsdb_table_upsert(&table_Wifi_Inet_State, &state, false))
|
||||
LOG(ERR, "inet_state: failed to insert");
|
||||
}
|
||||
@@ -289,6 +571,12 @@ void wifi_inet_master_set(struct blob_attr *msg)
|
||||
SCHEMA_SET_STR(state.port_state, "active");
|
||||
SCHEMA_SET_STR(state.network_state, "up");
|
||||
} else {
|
||||
/* Delete VLAN interface state column if disabled */
|
||||
if (strstr(state.if_name, "_") != NULL) {
|
||||
wifi_inet_master_del(state.if_name);
|
||||
return;
|
||||
}
|
||||
|
||||
SCHEMA_SET_STR(state.port_state, "inactive");
|
||||
SCHEMA_SET_STR(state.network_state, "down");
|
||||
}
|
||||
@@ -329,7 +617,14 @@ void wifi_inet_master_set(struct blob_attr *msg)
|
||||
|
||||
if (!net_is_bridge(l3_device))
|
||||
SCHEMA_SET_STR(state.if_type, "bridge");
|
||||
else
|
||||
/* Fill if_type, vlan_id and parent_ifname using
|
||||
* if_name (eg:eth0_100) */
|
||||
else if (!strncmp(l3_device, "eth", strlen("eth"))) {
|
||||
char *delim = NULL;
|
||||
delim = strstr(state.if_name, "_");
|
||||
if (delim)
|
||||
SCHEMA_SET_STR(state.if_type, "vlan");
|
||||
} else
|
||||
SCHEMA_SET_STR(state.if_type, "eth");
|
||||
} else
|
||||
SCHEMA_SET_STR(state.if_type, "eth");
|
||||
@@ -349,6 +644,17 @@ void wifi_inet_master_set(struct blob_attr *msg)
|
||||
LOG(ERR, "master_state: failed to insert");
|
||||
}
|
||||
|
||||
|
||||
bool wifi_inet_master_del(const char *ifname)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ovsdb_table_delete_simple(&table_Wifi_Master_State, SCHEMA_COLUMN(Wifi_Inet_State, if_name), ifname);
|
||||
if (ret <= 0)
|
||||
LOG(ERR, "inet_state: Error deleting Wifi_Master_State for interface %s.", ifname);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool wifi_inet_state_del(const char *ifname)
|
||||
{
|
||||
int ret;
|
||||
@@ -356,11 +662,6 @@ bool wifi_inet_state_del(const char *ifname)
|
||||
ret = ovsdb_table_delete_simple(&table_Wifi_Inet_State, SCHEMA_COLUMN(Wifi_Inet_State, if_name), ifname);
|
||||
if (ret <= 0)
|
||||
LOG(ERR, "inet_state: Error deleting Wifi_Inet_State for interface %s.", ifname);
|
||||
|
||||
ret = ovsdb_table_delete_simple(&table_Wifi_Master_State, SCHEMA_COLUMN(Wifi_Inet_State, if_name), ifname);
|
||||
if (ret <= 0)
|
||||
LOG(ERR, "inet_state: Error deleting Wifi_Master_State for interface %s.", ifname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/bin/sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
[ "$ACTION" = ifup -o "$ACTION" = ifupdate -o "$ACTION" = ifdown ] || exit 0
|
||||
|
||||
json_init
|
||||
json_load "$(cat /etc/board.json)"
|
||||
json_select network
|
||||
json_select "wan"
|
||||
json_get_vars ifname
|
||||
json_select ..
|
||||
json_select ..
|
||||
|
||||
[ -n "$ifname" ] || {
|
||||
ifname=$(uci get network.wan.ifname)
|
||||
ifname=${ifname%% *}
|
||||
}
|
||||
|
||||
if [ "$ACTION" = ifup -o "$ACTION" = ifupdate ]; then
|
||||
vid=$(uci get network.${INTERFACE}.vid)
|
||||
net=$(uci get network.${INTERFACE}.ifname)
|
||||
|
||||
[ -z "$net" -o -z "$vid" -o "$vid" = 0 ] && exit 0
|
||||
|
||||
bridge vlan add vid $vid dev br-lan self
|
||||
bridge vlan add vid $vid dev br-wan self
|
||||
bridge vlan add vid $vid dev $ifname
|
||||
bridge vlan add pvid $vid vid $vid dev $net untagged
|
||||
exit 0
|
||||
else
|
||||
if [ "$ACTION" = ifdown ]; then
|
||||
vid=`echo $INTERFACE | awk -F "_" '{ print $2 }'`
|
||||
net=`echo $INTERFACE | awk -F "_" '{ print $1 }'`
|
||||
[ -z "$net" -o -z "$vid" -o "$vid" = 0 ] && exit 0
|
||||
|
||||
bridge vlan del vid $vid dev $ifname
|
||||
bridge vlan del pvid $vid vid $vid dev $net untagged
|
||||
bridge vlan add pvid 1 vid 1 dev $net untagged
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
@@ -0,0 +1,85 @@
|
||||
From b14c0b96644cf86b36b0e60da800dd11733b26a9 Mon Sep 17 00:00:00 2001
|
||||
From: Chaitanya Godavarthi <chaitanya.kiran@netexperience.com>
|
||||
Date: Tue, 14 Sep 2021 10:23:49 -0400
|
||||
Subject: [PATCH] ubus notify when ethernet ports change state
|
||||
|
||||
Signed-off-by: Chaitanya Godavarthi <chaitanya.kiran@netexperience.com>
|
||||
---
|
||||
.../0106-add-ubus-notify-eth-state.patch | 65 +++++++++++++++++++
|
||||
1 file changed, 65 insertions(+)
|
||||
create mode 100644 package/network/config/netifd/patches/0106-add-ubus-notify-eth-state.patch
|
||||
|
||||
diff --git a/package/network/config/netifd/patches/0106-add-ubus-notify-eth-state.patch b/package/network/config/netifd/patches/0106-add-ubus-notify-eth-state.patch
|
||||
new file mode 100644
|
||||
index 0000000000..3c8eaa530d
|
||||
--- /dev/null
|
||||
+++ b/package/network/config/netifd/patches/0106-add-ubus-notify-eth-state.patch
|
||||
@@ -0,0 +1,65 @@
|
||||
+Index: netifd-2019-08-05-5e02f944/device.c
|
||||
+===================================================================
|
||||
+--- netifd-2019-08-05-5e02f944.orig/device.c
|
||||
++++ netifd-2019-08-05-5e02f944/device.c
|
||||
+@@ -29,6 +29,7 @@
|
||||
+ #include "netifd.h"
|
||||
+ #include "system.h"
|
||||
+ #include "config.h"
|
||||
++#include "ubus.h"
|
||||
+
|
||||
+ static struct list_head devtypes = LIST_HEAD_INIT(devtypes);
|
||||
+ static struct avl_tree devices;
|
||||
+@@ -638,6 +639,7 @@ void device_set_present(struct device *d
|
||||
+
|
||||
+ void device_set_link(struct device *dev, bool state)
|
||||
+ {
|
||||
++ ubus_link_state_notify(dev, state);
|
||||
+ if (dev->link_active == state)
|
||||
+ return;
|
||||
+
|
||||
+Index: netifd-2019-08-05-5e02f944/ubus.c
|
||||
+===================================================================
|
||||
+--- netifd-2019-08-05-5e02f944.orig/ubus.c
|
||||
++++ netifd-2019-08-05-5e02f944/ubus.c
|
||||
+@@ -817,6 +817,29 @@ netifd_dump_status(struct interface *ifa
|
||||
+ netifd_add_interface_errors(&b, iface);
|
||||
+ }
|
||||
+
|
||||
++void ubus_link_state_notify(struct device *dev, bool state)
|
||||
++{
|
||||
++ struct interface *iface = NULL;
|
||||
++ /* proceed to notify if eth link state change and bridge change */
|
||||
++ if((strncmp(dev->ifname, "eth", 3) && (dev->link_active == state)) &&
|
||||
++ strncmp(dev->ifname, "br-wan", 6) &&
|
||||
++ strncmp(dev->ifname, "br-lan", 6))
|
||||
++ return;
|
||||
++ netifd_log_message(L_NOTICE, "%s:%s\n", __func__, dev->ifname);
|
||||
++
|
||||
++ vlist_for_each_element(&interfaces, iface, node) {
|
||||
++ if( !strncmp(iface->name, "wan", 3) ||
|
||||
++ !strncmp(iface->name, "lan", 3) ||
|
||||
++ !strncmp(iface->name, "eth", 3)) {
|
||||
++ blob_buf_init(&b, 0);
|
||||
++ blobmsg_add_string(&b, "interface", iface->name);
|
||||
++ netifd_dump_status(iface);
|
||||
++ ubus_notify(ubus_ctx, &iface->ubus, "interface.update",
|
||||
++ b.head, -1);
|
||||
++ }
|
||||
++ }
|
||||
++}
|
||||
++
|
||||
+ static int
|
||||
+ netifd_handle_status(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
+ struct ubus_request_data *req, const char *method,
|
||||
+Index: netifd-2019-08-05-5e02f944/ubus.h
|
||||
+===================================================================
|
||||
+--- netifd-2019-08-05-5e02f944.orig/ubus.h
|
||||
++++ netifd-2019-08-05-5e02f944/ubus.h
|
||||
+@@ -22,5 +22,6 @@ void netifd_ubus_add_interface(struct in
|
||||
+ void netifd_ubus_remove_interface(struct interface *iface);
|
||||
+ void netifd_ubus_interface_event(struct interface *iface, bool up);
|
||||
+ void netifd_ubus_interface_notify(struct interface *iface, bool up);
|
||||
++void ubus_link_state_notify(struct device *dev, bool state);
|
||||
+
|
||||
+ #endif
|
||||
--
|
||||
2.25.1
|
||||
|
||||
Reference in New Issue
Block a user