lynxis lazus has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libosmocore/+/24591 )


Change subject: gprs_ns2_sns: implement outbound DEL SNS procedures
......................................................................

gprs_ns2_sns: implement outbound DEL SNS procedures

When removing a bind the remote side needs to be
informed via the SNS-DELETE procedure.

Related: OS#5036
Change-Id: I53cd54dfd262c70c425c3f13dad3b29526daa523
---
M src/gb/gprs_ns2_sns.c
1 file changed, 76 insertions(+), 7 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/91/24591/1

diff --git a/src/gb/gprs_ns2_sns.c b/src/gb/gprs_ns2_sns.c
index 656e06f..091a62b 100644
--- a/src/gb/gprs_ns2_sns.c
+++ b/src/gb/gprs_ns2_sns.c
@@ -592,6 +592,32 @@
        return -1;
 }

+static int remove_bind_elem(struct ns2_sns_state *gss, struct ns2_sns_elems 
*elems, struct ns2_sns_bind *sbind)
+{
+       struct gprs_ns_ie_ip4_elem ip4;
+       struct gprs_ns_ie_ip6_elem ip6;
+       const struct osmo_sockaddr *saddr = 
gprs_ns2_ip_bind_sockaddr(sbind->bind);
+
+       switch (saddr->u.sa.sa_family) {
+       case AF_INET:
+               ip4.ip_addr = saddr->u.sin.sin_addr.s_addr;
+               ip4.udp_port = saddr->u.sin.sin_port;
+               ip4.sig_weight = sbind->bind->sns_sig_weight;
+               ip4.data_weight = sbind->bind->sns_data_weight;
+               return remove_ip4_elem(gss, elems, &ip4);
+       case AF_INET6:
+               memcpy(&ip6.ip_addr, &saddr->u.sin6.sin6_addr, sizeof(struct 
in6_addr));
+               ip6.udp_port = saddr->u.sin.sin_port;
+               ip6.sig_weight = sbind->bind->sns_sig_weight;
+               ip6.data_weight = sbind->bind->sns_data_weight;
+               return remove_ip6_elem(gss, elems, &ip6);
+       default:
+               return -1;
+       }
+
+       return -1;
+}
+
 static int do_sns_change_weight(struct osmo_fsm_inst *fi, const struct 
gprs_ns_ie_ip4_elem *ip4, const struct gprs_ns_ie_ip6_elem *ip6)
 {
        struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
@@ -1484,6 +1510,12 @@
                else
                        ns2_tx_sns_change_weight(gss->sns_nsvc, 
gss->current_procedure->trans_id, NULL, 0, &gss->current_procedure->ip6, 1);
                break;
+       case SNS_DEL:
+               if (gss->family == AF_INET)
+                       ns2_tx_sns_del(gss->sns_nsvc, 
gss->current_procedure->trans_id, &gss->current_procedure->ip4, 1, NULL, 0);
+               else
+                       ns2_tx_sns_del(gss->sns_nsvc, 
gss->current_procedure->trans_id, NULL, 0, &gss->current_procedure->ip6, 1);
+               break;
        default:
                break;
        }
@@ -1596,8 +1628,11 @@
                                add_ip6_elem(gss, &gss->local, 
&gss->current_procedure->ip6);
                                break;
                        }
-                       create_nsvc_for_new_sbind(gss, 
gss->current_procedure->sbind);
-                       gprs_ns2_start_alive_all_nsvcs(nse);
+                       /* the sbind can be NULL if the bind has been released 
by del_bind */
+                       if (gss->current_procedure->sbind) {
+                               create_nsvc_for_new_sbind(gss, 
gss->current_procedure->sbind);
+                               gprs_ns2_start_alive_all_nsvcs(nse);
+                       }
                        break;
                case SNS_CHANGE_WEIGHT:
                        switch (gss->family) {
@@ -1630,6 +1665,16 @@
                                OSMO_ASSERT(0);
                        }
                        break;
+               case SNS_DEL:
+                       switch (gss->family) {
+                       case AF_INET:
+                               remove_ip4_elem(gss, &gss->local, 
&gss->current_procedure->ip4);
+                               break;
+                       case AF_INET6:
+                               remove_ip6_elem(gss, &gss->local, 
&gss->current_procedure->ip6);
+                               break;
+                       }
+                       break;
                default:
                        break;
                }
@@ -1851,6 +1896,8 @@
        switch (procedure_type) {
        case SNS_ADD:
                break;
+       case SNS_DEL:
+               break;
        case SNS_CHANGE_WEIGHT:
                llist_for_each_entry(procedure, &gss->procedures, list) {
                        if (procedure->sbind == sbind && procedure->procedure 
== procedure_type &&
@@ -1881,8 +1928,16 @@
        if (!procedure)
                return;

+       switch (procedure_type) {
+       case SNS_ADD:
+       case SNS_CHANGE_WEIGHT:
+               procedure->sbind = sbind;
+               break;
+       default:
+               break;
+       }
+
        llist_add_tail(&procedure->list, &gss->procedures);
-       procedure->sbind = sbind;
        procedure->procedure = procedure_type;
        procedure->sig_weight = sbind->bind->sns_sig_weight;
        procedure->data_weight = sbind->bind->sns_data_weight;
@@ -1895,7 +1950,6 @@
                procedure->ip4.data_weight = sbind->bind->sns_data_weight;
                break;
        case AF_INET6:
-
                memcpy(&procedure->ip6.ip_addr, &saddr->u.sin6.sin6_addr, 
sizeof(struct in6_addr));
                procedure->ip6.udp_port = saddr->u.sin.sin_port;
                procedure->ip6.sig_weight = sbind->bind->sns_sig_weight;
@@ -1950,6 +2004,7 @@
        struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
        struct ns2_sns_bind *sbind;
        struct gprs_ns2_vc *nsvc, *nsvc2;
+       struct ns2_sns_procedure *procedure;

        switch (event) {
        case GPRS_SNS_EV_REQ_ADD_BIND:
@@ -2022,25 +2077,39 @@
                case GPRS_SNS_ST_UNCONFIGURED:
                        break;
                case GPRS_SNS_ST_BSS_SIZE:
-                       /* TODO: remove the ip4 element from the list */
                        llist_for_each_entry_safe(nsvc, nsvc2, &nse->nsvc, 
list) {
                                if (nsvc->bind == sbind->bind) {
                                        gprs_ns2_free_nsvc(nsvc);
                                }
                        }
+                       osmo_fsm_inst_dispatch(fi, 
GPRS_SNS_EV_REQ_SELECT_ENDPOINT, NULL);
                        break;
                case GPRS_SNS_ST_BSS_CONFIG_BSS:
                case GPRS_SNS_ST_BSS_CONFIG_SGSN:
                case GPRS_SNS_ST_CONFIGURED:
-                       /* TODO: do an delete SNS-IP procedure */
-                       /* TODO: remove the ip4 element to the list */
+               case GPRS_SNS_ST_LOCAL_PROCEDURE:
+                       remove_bind_elem(gss, &gss->local_procedure, sbind);
+                       if (ip46_weight_sum(&gss->local_procedure, true) == 0 ||
+                                       ip46_weight_sum(&gss->local_procedure, 
false) == 0) {
+                               LOGPFSML(fi, LOGL_ERROR, "NSE %d: weight become 
invalid because of removing bind %s. Resetting the configuration\n",
+                                        nse->nsei, sbind->bind->name);
+                               osmo_fsm_inst_dispatch(fi, 
GPRS_SNS_EV_REQ_SELECT_ENDPOINT, NULL);
+                               break;
+                       }
                        llist_for_each_entry_safe(nsvc, nsvc2, &nse->nsvc, 
list) {
                                if (nsvc->bind == sbind->bind) {
                                        gprs_ns2_free_nsvc(nsvc);
                                }
                        }
+                       /* ensure other procedures doesn't use the sbind */
+                       llist_for_each_entry(procedure, &gss->procedures, list) 
{
+                               if (procedure->sbind == sbind)
+                                       procedure->sbind = NULL;
+                       }
+                       ns2_add_procedure(gss, sbind, SNS_DEL);
                        break;
                }
+
                /* if this is the last bind, the free_nsvc() will trigger a 
reselection */
                talloc_free(sbind);
                break;

--
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/24591
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I53cd54dfd262c70c425c3f13dad3b29526daa523
Gerrit-Change-Number: 24591
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <lyn...@fe80.eu>
Gerrit-MessageType: newchange

Reply via email to