Added comments to clarify the relationships
[mpls-ldp-portable.git] / ldp / ldp_addr.c
blobea8eb5a96883d7d6f4e7e6ae8e8f9ff4ebb1bde1
2 /*
3 * Copyright (C) James R. Leu 2000
4 * jleu@mindspring.com
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
8 */
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/socket.h>
13 #include "ldp_struct.h"
14 #include "ldp_session.h"
15 #include "ldp_entity.h"
16 #include "ldp_pdu_setup.h"
17 #include "ldp_addr.h"
18 #include "ldp_buf.h"
19 #include "ldp_mesg.h"
20 #include "mpls_ifmgr_impl.h"
21 #include "mpls_mm_impl.h"
22 #include "mpls_trace_impl.h"
23 #include "mpls_tree_impl.h"
25 static uint32_t _ldp_addr_next_index = 1;
27 ldp_addr *ldp_addr_create(mpls_inet_addr * address)
29 ldp_addr *a = (ldp_addr *) mpls_malloc(sizeof(ldp_addr));
31 if (a) {
32 MPLS_REFCNT_INIT(a, 0);
33 mpls_link_list_init(&a->session_root);
35 memcpy(&a->address, address, sizeof(mpls_inet_addr));
36 a->index = _ldp_addr_get_next_index();
38 return a;
41 void ldp_addr_delete(ldp_addr * a)
43 LDP_PRINT(g->user_data,"addr delete\n");
44 mpls_free(a);
47 mpls_return_enum _ldp_addr_add_session(ldp_addr * a, ldp_session * s)
49 MPLS_ASSERT(a && s);
50 MPLS_REFCNT_HOLD(s);
51 if (mpls_link_list_add_tail(&a->session_root, s) == MPLS_SUCCESS) {
52 return MPLS_SUCCESS;
54 MPLS_REFCNT_RELEASE(s, ldp_session_delete);
55 return MPLS_FAILURE;
58 void _ldp_addr_del_session(ldp_addr * a, ldp_session * s)
60 MPLS_ASSERT(a && s);
61 mpls_link_list_remove_data(&a->session_root, s);
62 MPLS_REFCNT_RELEASE(s, ldp_session_delete);
65 uint32_t _ldp_addr_get_next_index()
67 uint32_t retval = _ldp_addr_next_index;
69 _ldp_addr_next_index++;
70 if (retval > _ldp_addr_next_index) {
71 _ldp_addr_next_index = 1;
73 return retval;
76 void ldp_addr_mesg_prepare(ldp_mesg * msg, ldp_global * g, uint32_t msgid,
77 mpls_inet_addr * addr)
79 MPLS_MSGPTR(Adr);
81 LDP_ENTER(g->user_data, "ldp_addr_mesg_prepare");
83 ldp_mesg_prepare(msg, MPLS_ADDR_MSGTYPE, msgid);
84 MPLS_MSGPARAM(Adr) = &msg->u.addr;
86 MPLS_MSGPARAM(Adr)->adrListTlvExists = 1;
87 MPLS_MSGPARAM(Adr)->baseMsg.msgLength +=
88 setupAddrTlv(&(MPLS_MSGPARAM(Adr)->addressList));
90 MPLS_MSGPARAM(Adr)->baseMsg.msgLength +=
91 addAddrElem2AddrTlv(&(MPLS_MSGPARAM(Adr)->addressList), addr->u.ipv4);
93 LDP_EXIT(g->user_data, "ldp_addr_mesg_prepare");
96 void ldp_waddr_mesg_prepare(ldp_mesg * msg, ldp_global * g, uint32_t msgid,
97 mpls_inet_addr * addr)
99 MPLS_MSGPTR(Adr);
101 LDP_ENTER(g->user_data, "ldp_waddr_mesg_prepare");
103 ldp_mesg_prepare(msg, MPLS_ADDRWITH_MSGTYPE, msgid);
104 MPLS_MSGPARAM(Adr) = &msg->u.addr;
106 MPLS_MSGPARAM(Adr)->adrListTlvExists = 1;
107 MPLS_MSGPARAM(Adr)->baseMsg.msgLength +=
108 setupAddrTlv(&(MPLS_MSGPARAM(Adr)->addressList));
110 MPLS_MSGPARAM(Adr)->baseMsg.msgLength +=
111 addAddrElem2AddrTlv(&(MPLS_MSGPARAM(Adr)->addressList), addr->u.ipv4);
113 LDP_EXIT(g->user_data, "ldp_waddr_mesg_prepare");
116 mpls_return_enum ldp_addr_send(ldp_global * g, ldp_session * s,
117 mpls_inet_addr * a)
119 mpls_return_enum result = MPLS_FAILURE;
121 MPLS_ASSERT(s && a);
123 LDP_ENTER(g->user_data, "ldp_addr_send");
125 ldp_addr_mesg_prepare(s->tx_message, g, g->message_identifier++, a);
127 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ADDRESS,
128 "Addr Send: session(%d)\n", s->index);
130 result = ldp_mesg_send_tcp(g, s, s->tx_message);
132 LDP_EXIT(g->user_data, "ldp_addr_send");
134 return result;
137 mpls_return_enum ldp_waddr_send(ldp_global * g, ldp_session * s,
138 mpls_inet_addr * a)
140 mpls_return_enum result = MPLS_FAILURE;
142 MPLS_ASSERT(s && a);
144 LDP_ENTER(g->user_data, "ldp_waddr_send");
146 ldp_waddr_mesg_prepare(s->tx_message, g, g->message_identifier++, a);
148 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ADDRESS,
149 "Addr Withdraw Send: session(%d)\n", s->index);
151 result = ldp_mesg_send_tcp(g, s, s->tx_message);
153 LDP_EXIT(g->user_data, "ldp_waddr_send");
155 return result;
158 mpls_return_enum ldp_addr_process(ldp_global * g, ldp_session * s,
159 ldp_entity * e, ldp_mesg * msg)
161 mplsLdpAdrMsg_t *body = &msg->u.addr;
162 mpls_inet_addr inet;
163 ldp_addr *addr = NULL;
164 int len = (body->addressList.baseTlv.length - MPLS_ADDFAMFIXLEN) /
165 MPLS_IPv4LEN;
166 int i;
168 LDP_ENTER(g->user_data, "ldp_addr_process");
170 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_ADDRESS,
171 "Addr Recv: session(%d)\n", s->index);
173 for (i = 0; i < len; i++) {
174 inet.type = MPLS_FAMILY_IPV4;
175 inet.u.ipv4 = body->addressList.address[i];
177 if (msg->u.generic.flags.flags.msgType == MPLS_ADDR_MSGTYPE) {
178 if (mpls_tree_get(g->addr_tree, inet.u.ipv4, 32, (void **)&addr) ==
179 MPLS_FAILURE) {
180 /* it's not in the tree, put it there! */
181 if ((addr = ldp_addr_create(&inet)) == NULL) {
182 LDP_PRINT(g->user_data, "ldp_addr_process: error creating address\n");
183 goto ldp_addr_process_end;
185 MPLS_REFCNT_HOLD(addr);
186 if (mpls_tree_insert(g->addr_tree, inet.u.ipv4, 32, (void *)addr) ==
187 MPLS_FAILURE) {
188 LDP_PRINT(g->user_data, "ldp_addr_process: error adding addr\n");
189 goto ldp_addr_process_end;
193 /* the addr is in the tree */
194 if (ldp_session_add_addr(s, addr) == MPLS_FAILURE) {
195 LDP_PRINT(g->user_data,
196 "ldp_addr_process: error adding address to session\n");
197 return MPLS_FAILURE;
199 } else {
200 /* addr withdrawl */
201 if (mpls_tree_get(g->addr_tree, inet.u.ipv4, 32, (void **)&addr) ==
202 MPLS_SUCCESS) {
203 ldp_session_del_addr(s, addr);
204 if (MPLS_REFCNT_VALUE(addr) == 1) {
205 /* the tree is the last one holding a ref to this addr */
206 mpls_tree_remove(g->addr_tree, inet.u.ipv4, 32, (void **)&addr);
207 MPLS_REFCNT_RELEASE(addr, ldp_addr_delete);
213 LDP_EXIT(g->user_data, "ldp_addr_process");
215 return MPLS_SUCCESS;
217 ldp_addr_process_end:
218 if (addr != NULL)
219 ldp_addr_delete(addr);
221 LDP_EXIT(g->user_data, "ldp_addr_process-error");
223 return MPLS_FAILURE;