This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
lynxis lazus gerrit-no-reply at lists.osmocom.orglynxis lazus has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/24123 )
Change subject: gprs_ns2: implement outbound ADD/DEL SNS procedures
......................................................................
gprs_ns2: implement outbound ADD/DEL SNS procedures
When adding or removing a bind, the remote side needs to be
informed via the SNS-ADD/SNS-DELETE procedure.
Related: OS#5036
Change-Id: I71c33200bd1f0307ceb943ee958db5ebe3623d36
---
M src/gb/gprs_ns2_sns.c
1 file changed, 246 insertions(+), 43 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/23/24123/1
diff --git a/src/gb/gprs_ns2_sns.c b/src/gb/gprs_ns2_sns.c
index 7131974..accadac 100644
--- a/src/gb/gprs_ns2_sns.c
+++ b/src/gb/gprs_ns2_sns.c
@@ -124,6 +124,8 @@
enum sns_bind_flag {
SNS_BIND_CHANGE_REQ, /*!< request to change weights */
+ SNS_BIND_ADD_REQ, /*!< request to add */
+ SNS_BIND_DEL_REQ, /*!< request to delete */
};
struct sns_endpoint {
@@ -143,7 +145,7 @@
struct ns2_sns_bind {
struct llist_head list;
struct gprs_ns2_vc_bind *bind;
- uint8_t change_weight_state;
+ uint8_t procedure_state;
};
struct ns2_sns_state {
@@ -213,7 +215,7 @@
for (size_t i = 0; i < num; i++) {
if (ip4[i].ip_addr == saddr->u.sin.sin_addr.s_addr &&
- ip4->udp_port == saddr->u.sin.sin_port)
+ ip4[i].udp_port == saddr->u.sin.sin_port)
return &ip4[i];
}
@@ -469,6 +471,10 @@
if (bind->ll != GPRS_NS2_LL_UDP)
continue;
+ /* ignore binds which are about to be added or deleted */
+ if (sbind->procedure_state & (S(SNS_BIND_ADD_REQ) | S(SNS_BIND_DEL_REQ)))
+ continue;
+
nsvc = nsvc_for_bind_and_remote(nse, bind, &remote);
if (!nsvc) {
nsvc = gprs_ns2_ip_connect_inactive(bind, &remote, nse, 0);
@@ -500,6 +506,10 @@
if (bind->ll != GPRS_NS2_LL_UDP)
continue;
+ /* ignore binds which are about to be added or deleted */
+ if (sbind->procedure_state & (S(SNS_BIND_ADD_REQ) | S(SNS_BIND_DEL_REQ)))
+ continue;
+
/* we only care about UDP binds */
nsvc = nsvc_for_bind_and_remote(nse, bind, &remote);
if (!nsvc) {
@@ -521,6 +531,49 @@
return 0;
}
+/* Add a given local IPv4 element to gprs_sns_state */
+static int add_local_ip4_elem(struct ns2_sns_state *gss, uint32_t ip_addr, uint16_t port, uint16_t sig_weight, uint16_t data_weight)
+{
+ unsigned int i;
+
+ if (gss->num_ip4_local + gss->num_ip4_remote >= gss->num_max_nsvcs)
+ return -NS_CAUSE_INVAL_NR_NS_VC;
+
+ /* check for duplicates */
+ for (i = 0; i < gss->num_ip4_local; i++) {
+ if (gss->ip4_local[i].ip_addr != ip_addr || gss->ip4_local[i].udp_port != port)
+ continue;
+ /* TODO: log message duplicate */
+ /* TODO: check if this is the correct cause code */
+ return -NS_CAUSE_PROTO_ERR_UNSPEC;
+ }
+
+ gss->ip4_local = talloc_realloc(gss, gss->ip4_local, struct gprs_ns_ie_ip4_elem,
+ gss->num_ip4_local+1);
+ gss->ip4_local[gss->num_ip4_local].ip_addr = ip_addr;
+ gss->ip4_local[gss->num_ip4_local].udp_port = port;
+ gss->ip4_local[gss->num_ip4_local].sig_weight = sig_weight;
+ gss->ip4_local[gss->num_ip4_local].data_weight = data_weight;
+ gss->num_ip4_local += 1;
+ return 0;
+}
+
+/* Remove a given local IPv4 element from gprs_sns_state */
+static int remove_local_ip4_elem(struct ns2_sns_state *gss, const struct gprs_ns_ie_ip4_elem *ip4)
+{
+ unsigned int i;
+
+ for (i = 0; i < gss->num_ip4_local; i++) {
+ if (memcmp(&gss->ip4_local[i], ip4, sizeof(*ip4)))
+ continue;
+ /* all array elements < i remain as they are; all > i are shifted left by one */
+ memmove(&gss->ip4_local[i], &gss->ip4_local[i+1], gss->num_ip4_local-i-1);
+ gss->num_ip4_local -= 1;
+ return 0;
+ }
+ return -1;
+}
+
/* Add a given remote IPv4 element to gprs_sns_state */
static int add_remote_ip4_elem(struct ns2_sns_state *gss, const struct gprs_ns_ie_ip4_elem *ip4)
{
@@ -577,6 +630,49 @@
return -1;
}
+/* Add a given local IPv6 element to gprs_sns_state */
+static int add_local_ip6_elem(struct ns2_sns_state *gss, const struct in6_addr *ip_addr, uint16_t port, uint16_t sig_weight, uint16_t data_weight)
+{
+ unsigned int i;
+
+ if (gss->num_ip6_local + gss->num_ip6_remote >= gss->num_max_nsvcs)
+ return -NS_CAUSE_INVAL_NR_NS_VC;
+
+ /* check for duplicates */
+ for (i = 0; i < gss->num_ip6_local; i++) {
+ if (memcmp(&gss->ip6_local[i].ip_addr, ip_addr, sizeof(struct in6_addr)) || gss->ip6_local[i].udp_port != port)
+ continue;
+ /* TODO: log message duplicate */
+ /* TODO: check if this is the correct cause code */
+ return -NS_CAUSE_PROTO_ERR_UNSPEC;
+ }
+
+ gss->ip6_local = talloc_realloc(gss, gss->ip6_local, struct gprs_ns_ie_ip6_elem,
+ gss->num_ip6_local+1);
+ memcpy(&gss->ip6_local[gss->num_ip6_local].ip_addr, ip_addr, sizeof(struct in6_addr));
+ gss->ip6_local[gss->num_ip6_local].udp_port = port;
+ gss->ip6_local[gss->num_ip6_local].sig_weight = sig_weight;
+ gss->ip6_local[gss->num_ip6_local].data_weight = data_weight;
+ gss->num_ip6_local += 1;
+ return 0;
+}
+
+/* Remove a given local IPv4 element from gprs_sns_state */
+static int remove_local_ip6_elem(struct ns2_sns_state *gss, const struct gprs_ns_ie_ip6_elem *ip6)
+{
+ unsigned int i;
+
+ for (i = 0; i < gss->num_ip6_local; i++) {
+ if (memcmp(&gss->ip6_local[i], ip6, sizeof(*ip6)))
+ continue;
+ /* all array elements < i remain as they are; all > i are shifted left by one */
+ memmove(&gss->ip6_local[i], &gss->ip6_local[i+1], gss->num_ip6_local-i-1);
+ gss->num_ip6_local -= 1;
+ return 0;
+ }
+ return -1;
+}
+
/* Add a given remote IPv6 element to gprs_sns_state */
static int add_remote_ip6_elem(struct ns2_sns_state *gss, const struct gprs_ns_ie_ip6_elem *ip6)
{
@@ -826,6 +922,9 @@
const struct osmo_sockaddr *sa = gprs_ns2_ip_bind_sockaddr(sbind->bind);
if (!sa)
continue;
+ /* ignore binds which will be added in the future via a procedure */
+ if (sbind->procedure_state & S(SNS_BIND_ADD_REQ))
+ continue;
switch (stype) {
case IPv4:
@@ -864,7 +963,7 @@
remote = gprs_ns2_ip_vc_remote(gss->sns_nsvc);
/* count how many bindings are available (only UDP binds) */
- count = llist_count(&gss->binds);
+ count = ns2_sns_count_num_local_ep(fi, gss->ip);
if (count == 0) {
LOGPFSML(fi, LOGL_ERROR, "No local binds for this NSE -> cannot determine IP endpoints\n");
return;
@@ -879,6 +978,9 @@
gss->ip4_local = ip4_elems;
llist_for_each_entry(sbind, &gss->binds, list) {
bind = sbind->bind;
+ if (sbind->procedure_state & S(GPRS_SNS_EV_REQ_ADD_BIND))
+ continue;
+
sa = gprs_ns2_ip_bind_sockaddr(bind);
if (!sa)
continue;
@@ -915,6 +1017,9 @@
llist_for_each_entry(sbind, &gss->binds, list) {
bind = sbind->bind;
+ if (sbind->procedure_state & S(GPRS_SNS_EV_REQ_ADD_BIND))
+ continue;
+
sa = gprs_ns2_ip_bind_sockaddr(bind);
if (!sa)
continue;
@@ -944,16 +1049,29 @@
}
}
+static void ns2_sns_clean_procedures(struct ns2_sns_state *gss)
+{
+ struct ns2_sns_bind *sbind, *tmp;
+ llist_for_each_entry_safe(sbind, tmp, &gss->binds, list) {
+ if (sbind->procedure_state & S(SNS_BIND_DEL_REQ)) {
+ llist_del(&sbind->list);
+ talloc_free(sbind);
+ } else {
+ sbind->procedure_state = 0;
+ }
+ }
+}
+
static void ns2_sns_choose_next_bind(struct ns2_sns_state *gss)
{
/* take the first bind or take the next bind */
if (!gss->initial_bind) {
- gss->initial_bind = llist_first_entry(&gss->binds, struct ns2_sns_bind, list);
+ gss->initial_bind = llist_first_entry_or_null(&gss->binds, struct ns2_sns_bind, list);
} else {
if (gss->initial_bind->list.next != &gss->binds) {
gss->initial_bind = llist_entry(gss->initial_bind->list.next, struct ns2_sns_bind, list);
} else {
- gss->initial_bind = llist_first_entry(&gss->binds, struct ns2_sns_bind, list);
+ gss->initial_bind = llist_first_entry_or_null(&gss->binds, struct ns2_sns_bind, list);
}
}
}
@@ -963,6 +1081,7 @@
{
struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
+ // TODO: check if bss is even valid ! */
OSMO_ASSERT(gss->role == GPRS_SNS_ROLE_BSS);
/* on a generic failure, the timer callback will recover */
@@ -975,6 +1094,7 @@
gss->alive = false;
ns2_sns_compute_local_ep_from_binds(fi);
+ ns2_sns_clean_procedures(gss);
ns2_sns_choose_next_bind(gss);
/* setup the NSVC */
@@ -1420,9 +1540,11 @@
static void ns2_sns_st_configured_onenter(struct osmo_fsm_inst *fi, uint32_t old_state)
{
- struct gprs_ns2_vc *nsvc;
struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
struct gprs_ns2_nse *nse = nse_inst_from_fi(fi);
+ struct gprs_ns2_inst *nsi = nse->nsi;
+ struct gprs_ns2_vc *nsvc;
+ struct ns2_sns_bind *sbind;
/* NS-VC status updates are only parsed in ST_CONFIGURED.
* Do an initial check if there are any nsvc alive atm */
llist_for_each_entry(nsvc, &nse->nsvc, list) {
@@ -1439,31 +1561,54 @@
if (old_state != GPRS_SNS_ST_LOCAL_PROCEDURE)
ns2_prim_status_ind(nse, NULL, 0, GPRS_NS2_AFF_CAUSE_SNS_CONFIGURED);
+
+ /* check if there are procedure waiting */
+ llist_for_each_entry(sbind, &gss->binds, list) {
+ if (sbind->procedure_state) {
+ osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_LOCAL_PROCEDURE,
+ nsi->timeout[NS_TOUT_TSNS_PROV], GPRS_SNS_ST_LOCAL_PROCEDURE);
+ break;
+ }
+ }
}
static void ns2_sns_st_local_procedure_onenter(struct osmo_fsm_inst *fi, uint32_t old_state)
{
struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
+ struct gprs_ns2_nse *nse = nse_inst_from_fi(fi);
struct ns2_sns_bind *sns_bind;
if (gss->current_procedure.procedure == SNS_NONE) {
gss->N = 0;
/* select the next procedure */
+ // TODO: first check for BIND_ADD_REQ, then UPDATE_WEIGHT, then DELETE
llist_for_each_entry(sns_bind, &gss->binds, list) {
- if (sns_bind->change_weight_state & S(SNS_BIND_CHANGE_REQ)) {
- sns_bind->change_weight_state = 0;
+ if (sns_bind->procedure_state & S(SNS_BIND_ADD_REQ)) {
+ sns_bind->procedure_state = 0;
+ gss->current_procedure.procedure = SNS_ADD;
gss->current_procedure.bind = sns_bind;
+ break;
+ } else if (sns_bind->procedure_state & S(SNS_BIND_CHANGE_REQ)) {
+ sns_bind->procedure_state = 0;
gss->current_procedure.procedure = SNS_CHANGE_WEIGHT;
- ns2_procedure_set_endpoint(gss);
+ gss->current_procedure.bind = sns_bind;
+ break;
+ } else if (sns_bind->procedure_state & S(SNS_BIND_DEL_REQ)) {
+ sns_bind->procedure_state = 0;
+ gss->current_procedure.procedure = SNS_DEL;
+ gss->current_procedure.bind = sns_bind;
break;
}
}
+ // TODO: when add still set, take care of change weights at the same time (e.g. add a bind and change the weight at the same time)
if (gss->current_procedure.procedure == SNS_NONE) {
/* nothing to do */
osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_CONFIGURED, 0, 0);
return;
}
+
+ ns2_procedure_set_endpoint(gss);
gss->current_procedure.trans_id++;
if (gss->current_procedure.trans_id == 0)
gss->current_procedure.trans_id = 1;
@@ -1476,6 +1621,8 @@
ns2_tx_sns_add(gss->sns_nsvc, gss->current_procedure.trans_id, gss->current_procedure.ip4, 1, NULL, 0);
else
ns2_tx_sns_add(gss->sns_nsvc, gss->current_procedure.trans_id, NULL, 0, gss->current_procedure.ip6, 1);
+ create_missing_nsvcs(fi);
+ gprs_ns2_start_alive_all_nsvcs(nse);
break;
case SNS_CHANGE_WEIGHT:
if (gss->ip == IPv4)
@@ -1500,7 +1647,7 @@
struct gprs_ns2_nse *nse = nse_inst_from_fi(fi);
struct gprs_ns2_inst *nsi = nse->nsi;
struct tlv_parsed *tp = data;
- uint8_t trans_id;
+ uint8_t trans_id, cause;
switch (event) {
case GPRS_SNS_EV_RX_ADD:
@@ -1521,16 +1668,26 @@
break;
}
- if (!TLVP_PRESENT(tp, NS_IE_CAUSE)) {
- gss->current_procedure.procedure = SNS_NONE;
- /* everything ok, local_procedure_onenter() will check if there are more procedures required */
-
- osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_LOCAL_PROCEDURE,
- nsi->timeout[NS_TOUT_TSNS_PROV], GPRS_SNS_ST_LOCAL_PROCEDURE);
- return;
- } else {
+ if (TLVP_PRESENT(tp, NS_IE_CAUSE)) {
+ cause = tlvp_val8(tp, NS_IE_CAUSE, 0);
/* what happend on error cause? return to size? */
+ LOGPFSML(fi, LOGL_ERROR, "NSEI=%u Rx SNS ACK with cause code %d. Resetting SNS\n",
+ nse->nsei, cause);
+ osmo_fsm_inst_dispatch(fi, GPRS_SNS_EV_REQ_SELECT_ENDPOINT, NULL);
+ break;
}
+
+ // TODO: cleanup the bind also on SIZE or other failures
+ if (gss->current_procedure.procedure == SNS_DEL) {
+ talloc_free(gss->current_procedure.bind);
+ gss->current_procedure.bind = NULL;
+ }
+
+ gss->current_procedure.procedure = SNS_NONE;
+ /* everything ok, local_procedure_onenter() will check if there are more procedures required */
+
+ osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_LOCAL_PROCEDURE,
+ nsi->timeout[NS_TOUT_TSNS_PROV], GPRS_SNS_ST_LOCAL_PROCEDURE);
break;
}
}
@@ -1653,6 +1810,7 @@
/* common allstate-action for both roles */
static void ns2_sns_st_all_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
+ struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
struct gprs_ns2_nse *nse = nse_inst_from_fi(fi);
struct ns2_sns_bind *sbind;
struct gprs_ns2_vc *nsvc, *nsvc2;
@@ -1662,45 +1820,57 @@
sbind = data;
switch (fi->state) {
case GPRS_SNS_ST_UNCONFIGURED:
- osmo_fsm_inst_dispatch(nse->bss_sns_fi, GPRS_SNS_EV_REQ_SELECT_ENDPOINT, NULL);
+ osmo_fsm_inst_dispatch(fi, GPRS_SNS_EV_REQ_SELECT_ENDPOINT, NULL);
break;
case GPRS_SNS_ST_BSS_SIZE:
- /* TODO: add the ip4 element to the list */
+ osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_BSS_SIZE, nse->nsi->timeout[NS_TOUT_TSNS_PROV], 1);
break;
case GPRS_SNS_ST_BSS_CONFIG_BSS:
case GPRS_SNS_ST_BSS_CONFIG_SGSN:
+ sbind->procedure_state |= S(SNS_BIND_ADD_REQ);
+ break;
case GPRS_SNS_ST_CONFIGURED:
- /* TODO: add to SNS-IP procedure queue & add nsvc() */
+ sbind->procedure_state |= S(SNS_BIND_ADD_REQ);
+ osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_LOCAL_PROCEDURE, nse->nsi->timeout[NS_TOUT_TSNS_PROV], GPRS_SNS_ST_LOCAL_PROCEDURE);
+ break;
+ case GPRS_SNS_ST_LOCAL_PROCEDURE:
break;
}
break;
case GPRS_SNS_EV_REQ_DELETE_BIND:
sbind = data;
+ sbind->procedure_state |= S(SNS_BIND_DEL_REQ);
switch (fi->state) {
case GPRS_SNS_ST_UNCONFIGURED:
+ llist_del(&sbind->list);
+ talloc_free(sbind);
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);
+ if (sbind == gss->initial_bind) {
+ /* keep the order of binds */
+ ns2_sns_choose_next_bind(gss);
+ if (sbind == gss->initial_bind)
+ gss->initial_bind = NULL;
+ llist_del(&sbind->list);
+ llist_for_each_entry_safe(nsvc, nsvc2, &nse->nsvc, list) {
+ if (nsvc->bind == sbind->bind) {
+ gprs_ns2_free_nsvc(nsvc);
+ }
}
+ } else {
+ llist_del(&sbind->list);
}
+ talloc_free(sbind);
break;
case GPRS_SNS_ST_BSS_CONFIG_BSS:
case GPRS_SNS_ST_BSS_CONFIG_SGSN:
+ break;
case GPRS_SNS_ST_CONFIGURED:
- /* TODO: do an delete SNS-IP procedure */
- /* TODO: remove the ip4 element to 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_state_chg(fi, GPRS_SNS_ST_LOCAL_PROCEDURE, nse->nsi->timeout[NS_TOUT_TSNS_PROV], GPRS_SNS_ST_LOCAL_PROCEDURE);
+ break;
+ case GPRS_SNS_ST_LOCAL_PROCEDURE:
break;
}
- /* if this is the last bind, the free_nsvc() will trigger a reselection */
- talloc_free(sbind);
break;
case GPRS_SNS_EV_REQ_CHANGE_WEIGHT:
sbind = data;
@@ -1710,11 +1880,21 @@
/* unconfigured or size don't need a procedure */
break;
/* all other states */
- default:
- /* change the flag */
- sbind->change_weight_state |= S(SNS_BIND_CHANGE_REQ);
+ case GPRS_SNS_ST_BSS_CONFIG_BSS:
+ case GPRS_SNS_ST_BSS_CONFIG_SGSN:
+ case GPRS_SNS_ST_CONFIGURED:
+ /* ignore update weights when the bind hasn't added */
+ if (sbind->procedure_state & S(SNS_BIND_ADD_REQ))
+ return;
+ sbind->procedure_state |= S(SNS_BIND_CHANGE_REQ);
osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_LOCAL_PROCEDURE, nse->nsi->timeout[NS_TOUT_TSNS_PROV], GPRS_SNS_ST_LOCAL_PROCEDURE);
break;
+ case GPRS_SNS_ST_LOCAL_PROCEDURE:
+ /* ignore update weights when the bind hasn't added */
+ if (sbind->procedure_state & S(SNS_BIND_ADD_REQ))
+ return;
+ sbind->procedure_state |= S(SNS_BIND_DEL_REQ);
+ break;
}
break;
}
@@ -1745,7 +1925,9 @@
ns2_clear_ipv46_entries_remote(gss);
/* Choose the next sns endpoint. */
- if (llist_empty(&gss->sns_endpoints) || llist_empty(&gss->binds)) {
+ ns2_sns_clean_procedures(gss);
+ ns2_sns_choose_next_bind(gss);
+ if (llist_empty(&gss->sns_endpoints) || !gss->initial_bind) {
gss->initial = NULL;
ns2_prim_status_ind(gss->nse, NULL, 0, GPRS_NS2_AFF_CAUSE_SNS_NO_ENDPOINTS);
osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_UNCONFIGURED, 0, 3);
@@ -2167,7 +2349,6 @@
return -ENOMEM;
tmp->bind = bind;
llist_add_tail(&tmp->list, &gss->binds);
-
osmo_fsm_inst_dispatch(nse->bss_sns_fi, GPRS_SNS_EV_REQ_ADD_BIND, tmp);
return 0;
}
@@ -2193,7 +2374,6 @@
llist_for_each_entry_safe(tmp, tmp2, &gss->binds, list) {
if (tmp->bind == bind) {
- llist_del(&tmp->list);
found = true;
break;
}
@@ -2212,6 +2392,7 @@
const struct osmo_sockaddr *sa;
struct gprs_ns_ie_ip4_elem *ip4;
struct gprs_ns_ie_ip6_elem *ip6;
+ int rc;
/* TODO: ensure this bind is already added! */
OSMO_ASSERT(gss->current_procedure.procedure != SNS_NONE);
@@ -2229,8 +2410,18 @@
ip4 = ip4_elem_by_saddr(gss->ip4_local, gss->num_ip4_local, sa);
}
- /* TODO: check if this bind is about to be added */
- OSMO_ASSERT(ip4);
+ if (gss->current_procedure.procedure == SNS_CHANGE_WEIGHT || gss->current_procedure.procedure == SNS_DEL) {
+ /* for SNS-UPDATE-PROCEDURE we need to find an endpoint */
+ OSMO_ASSERT(ip4);
+ } else if (gss->current_procedure.procedure == SNS_ADD) {
+ OSMO_ASSERT(!ip4);
+ rc = add_local_ip4_elem(gss, sa->u.sin.sin_addr.s_addr, sa->u.sin.sin_port,
+ gss->current_procedure.bind->bind->sns_sig_weight,
+ gss->current_procedure.bind->bind->sns_data_weight);
+ OSMO_ASSERT(!rc);
+ ip4 = &gss->ip4_local[gss->num_ip4_local - 1];
+ }
+
gss->current_procedure.ip4 = ip4;
break;
case AF_INET6:
@@ -2242,7 +2433,19 @@
} else {
ip6 = ip6_elem_by_saddr(gss->ip6_local, gss->num_ip6_local, sa);
}
- OSMO_ASSERT(ip6);
+
+ /* for SNS-UPDATE-PROCEDURE we need to find an endpoint */
+ if (gss->current_procedure.procedure == SNS_CHANGE_WEIGHT || gss->current_procedure.procedure == SNS_DEL) {
+ OSMO_ASSERT(ip6);
+ } else if (gss->current_procedure.procedure == SNS_ADD) {
+ OSMO_ASSERT(!ip6);
+ rc = add_local_ip6_elem(gss, &sa->u.sin6.sin6_addr, sa->u.sin6.sin6_port,
+ gss->current_procedure.bind->bind->sns_sig_weight,
+ gss->current_procedure.bind->bind->sns_data_weight);
+ OSMO_ASSERT(!rc);
+ ip6 = &gss->ip6_local[gss->num_ip6_local - 1];
+ }
+
gss->current_procedure.ip6 = ip6;
break;
default:
--
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/24123
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I71c33200bd1f0307ceb943ee958db5ebe3623d36
Gerrit-Change-Number: 24123
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <lynxis at fe80.eu>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210504/53b82c99/attachment.htm>