Introduce a new device event "topology change" that gets signaled
by bridges on adding/removing members.

On "topology changes" the proto handlers are requested to "renew"
which is most useful for DHCP.

Signed-off-by: Helmut Schaa <[email protected]>
---
 bridge.c                | 4 ++++
 device.h                | 3 +++
 interface.c             | 5 +++++
 proto-shell.c           | 2 ++
 proto-static.c          | 1 +
 proto.c                 | 3 +++
 proto.h                 | 2 ++
 scripts/netifd-proto.sh | 8 +++++++-
 vlan.c                  | 4 ++++
 9 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/bridge.c b/bridge.c
index 147fe0a..6baef29 100644
--- a/bridge.c
+++ b/bridge.c
@@ -140,6 +140,8 @@ bridge_disable_member(struct bridge_member *bm)
        system_bridge_delif(&bst->dev, bm->dev.dev);
        device_release(&bm->dev);
 
+       device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
+
        return 0;
 }
 
@@ -162,6 +164,8 @@ bridge_enable_member(struct bridge_member *bm)
                goto error;
        }
 
+       device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
+
        return 0;
 
 error:
diff --git a/device.h b/device.h
index dd57927..8d2aca6 100644
--- a/device.h
+++ b/device.h
@@ -78,6 +78,9 @@ enum device_event {
        DEV_EVENT_LINK_UP,
        DEV_EVENT_LINK_DOWN,
 
+       /* Topology changed (i.e. bridge member added) */
+       DEV_EVENT_TOPO_CHANGE, 
+
        __DEV_EVENT_MAX
 };
 
diff --git a/interface.c b/interface.c
index 39460e4..ad60298 100644
--- a/interface.c
+++ b/interface.c
@@ -328,6 +328,9 @@ interface_cb(struct device_user *dep, enum device_event ev)
         case DEV_EVENT_LINK_DOWN:
                interface_set_link_state(iface, new_state);
                break;
+       case DEV_EVENT_TOPO_CHANGE:
+               interface_proto_event(iface->proto, PROTO_CMD_RENEW, false);
+               return;
        default:
                break;
        }
@@ -599,6 +602,8 @@ interface_proto_cb(struct interface_proto_state *state, 
enum interface_proto_eve
                mark_interface_down(iface);
                iface->state = IFS_SETUP;
                break;
+       default:
+               return;
        }
 
        interface_write_resolv_conf();
diff --git a/proto-shell.c b/proto-shell.c
index 9041045..a8c6f0b 100644
--- a/proto-shell.c
+++ b/proto-shell.c
@@ -159,6 +159,8 @@ proto_shell_handler(struct interface_proto_state *proto,
                state->last_error = -1;
                proto_shell_clear_host_dep(state);
                state->sm = S_SETUP;
+       } else if (cmd == PROTO_CMD_RENEW) {
+               action = "renew";
        } else {
                if (state->sm == S_TEARDOWN)
                        return 0;
diff --git a/proto-static.c b/proto-static.c
index 77a536a..b492d92 100644
--- a/proto-static.c
+++ b/proto-static.c
@@ -52,6 +52,7 @@ static_handler(struct interface_proto_state *proto,
 
                break;
        case PROTO_CMD_TEARDOWN:
+       case PROTO_CMD_RENEW:
                break;
        }
 
diff --git a/proto.c b/proto.c
index 64be308..3a7b2a8 100644
--- a/proto.c
+++ b/proto.c
@@ -615,6 +615,9 @@ interface_proto_event(struct interface_proto_state *proto,
        case PROTO_CMD_TEARDOWN:
                ev = IFPEV_DOWN;
                break;
+       case PROTO_CMD_RENEW:
+               ev = IFPEV_RENEW;
+               break;
        default:
                return -EINVAL;
        }
diff --git a/proto.h b/proto.h
index e402a91..c3264fb 100644
--- a/proto.h
+++ b/proto.h
@@ -22,11 +22,13 @@ enum interface_proto_event {
        IFPEV_UP,
        IFPEV_DOWN,
        IFPEV_LINK_LOST,
+       IFPEV_RENEW,
 };
 
 enum interface_proto_cmd {
        PROTO_CMD_SETUP,
        PROTO_CMD_TEARDOWN,
+       PROTO_CMD_RENEW,
 };
 
 enum {
diff --git a/scripts/netifd-proto.sh b/scripts/netifd-proto.sh
index 7f08b1d..debfaa7 100644
--- a/scripts/netifd-proto.sh
+++ b/scripts/netifd-proto.sh
@@ -20,6 +20,11 @@ _proto_do_teardown() {
        eval "proto_$1_teardown \"$interface\" \"$ifname\""
 }
 
+_proto_do_renew() {
+       json_load "$data"
+       eval "proto_$1_renew \"$interface\" \"$ifname\""
+}
+
 _proto_do_setup() {
        json_load "$data"
        _EXPORT_VAR=0
@@ -365,7 +370,7 @@ init_proto() {
                                json_dump
                        }
                ;;
-               setup|teardown)
+               setup|teardown|renew)
                        interface="$1"; shift
                        data="$1"; shift
                        ifname="$1"; shift
@@ -376,6 +381,7 @@ init_proto() {
                                case "$cmd" in
                                        setup) _proto_do_setup "$1";;
                                        teardown) _proto_do_teardown "$1" ;;
+                                       renew) _proto_do_renew "$1" ;;
                                        *) return 1 ;;
                                esac
                        }
diff --git a/vlan.c b/vlan.c
index 9201979..ce7e8cf 100644
--- a/vlan.c
+++ b/vlan.c
@@ -88,6 +88,10 @@ static void vlan_dev_cb(struct device_user *dep, enum 
device_event ev)
                vlan_dev_set_name(vldev, dep->dev);
                device_broadcast_event(&vldev->dev, ev);
                break;
+       case DEV_EVENT_TOPO_CHANGE:
+               /* Propagate topo changes */
+               device_broadcast_event(&ost->dev, DEV_EVENT_TOPO_CHANGE);
+               break;
        default:
                break;
        }
-- 
1.8.1.4
_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to