52
52
#define NCACHE_GC_PERIOD 20 /* seconds */
53
53
#define DCACHE_GC_PERIOD 20 /* seconds */
54
54
55
- static uint16_t current_max_cache = 64 ;
55
+ /* Neighbour Cache garbage collection parameters (per interface) */
56
+ /* Parameters only for garbage-collectible entries; registered entries counted separately */
57
+ #define NCACHE_MAX_LONG_TERM 8 /* Target for basic GC - expire old entries if more than this */
58
+ #define NCACHE_MAX_SHORT_TERM 32 /* Expire stale entries if more than this */
59
+ #define NCACHE_MAX_ABSOLUTE 64 /* Never have more than this */
60
+ #define NCACHE_GC_AGE 600 /* 10 minutes (1s units - decremented every slow timer call) */
61
+
62
+ /* Destination Cache garbage collection parameters (system-wide) */
63
+ #define DCACHE_MAX_LONG_TERM 16
64
+ #define DCACHE_MAX_SHORT_TERM 40
65
+ #define DCACHE_MAX_ABSOLUTE 64 /* Never have more than this */
66
+ #define DCACHE_GC_AGE (30 * DCACHE_GC_PERIOD) /* 10 minutes */
67
+
68
+ typedef struct destination_cache_configuration_s {
69
+ uint16_t max_entries ; // Never have more than this
70
+ uint16_t short_term_entries ; // Expire stale entries if more than this
71
+ uint16_t long_term_entries ; // Target for basic GC - expire old entries if more than this
72
+ uint16_t entry_lifetime ; // 20s units - decremented once per periodic GC
73
+ } destination_cache_config_t ;
74
+
75
+ typedef struct neighbour_cache_configuration_s {
76
+ uint16_t max_entries ; // Never have more than this
77
+ uint16_t short_term_entries ; // Expire stale entries if more than this
78
+ uint16_t long_term_entries ; // Target for basic GC - expire old entries if more than this
79
+ uint16_t entry_lifetime ; // 1s units - decremented every slow timer call
80
+ } neighbour_cache_config_t ;
81
+
82
+ static destination_cache_config_t destination_cache_config = {DCACHE_MAX_ABSOLUTE , DCACHE_MAX_SHORT_TERM , DCACHE_MAX_LONG_TERM , DCACHE_GC_AGE };
83
+ static neighbour_cache_config_t neighbour_cache_config = {NCACHE_MAX_ABSOLUTE , NCACHE_MAX_SHORT_TERM , NCACHE_MAX_LONG_TERM , NCACHE_GC_AGE };
56
84
57
85
/* We track "lifetime" of garbage-collectible entries, resetting
58
86
* when used. Entries with lifetime 0 are favoured
59
87
* for garbage-collection. */
60
- #define NCACHE_GC_AGE 600 /* 10 minutes (1s units - decremented every slow timer call) */
61
- #define DCACHE_GC_AGE 30 /* 10 minutes (20s units - decremented once per periodic GC) */
62
- #define DCACHE_GC_AGE_LL 6 /* 2 minutes for link-local destinations */
88
+ #define DCACHE_GC_AGE_LL (120 / DCACHE_GC_PERIOD) /* 2 minutes for link-local destinations, in DCACHE_GC_PERIOD intervals */
63
89
64
90
/* For probable routers, consider them unreachable if ETX is greater than this */
65
91
#define ETX_REACHABILITY_THRESHOLD 0x200 /* 8.8 fixed-point, so 2 */
@@ -79,27 +105,6 @@ static uint8_t ipv6_route_table_get_max_entries(int8_t interface_id, ipv6_route_
79
105
80
106
static uint16_t dcache_gc_timer ;
81
107
82
- static uint16_t cache_long_term (bool is_destination )
83
- {
84
- uint16_t value = current_max_cache / 8 ;
85
- if (is_destination ) {
86
- value *= 2 ;
87
- }
88
- if (value < 4 ) {
89
- value = 4 ;
90
- }
91
- return value ;
92
- }
93
-
94
- static uint16_t cache_short_term (bool is_destination )
95
- {
96
- uint16_t value = current_max_cache / 2 ;
97
- if (value < cache_long_term (is_destination )) {
98
- return cache_long_term (is_destination );
99
- }
100
- return value ;
101
- }
102
-
103
108
static uint32_t next_probe_time (ipv6_neighbour_cache_t * cache , uint_fast8_t retrans_num )
104
109
{
105
110
uint32_t t = cache -> retrans_timer ;
@@ -120,7 +125,57 @@ int8_t ipv6_neighbour_set_current_max_cache(uint16_t max_cache)
120
125
if (max_cache < 4 ) {
121
126
return -1 ;
122
127
}
123
- current_max_cache = max_cache ;
128
+
129
+ // adjust destination cache
130
+ destination_cache_config .max_entries = max_cache ;
131
+ destination_cache_config .long_term_entries = max_cache / 4 ;
132
+ if (destination_cache_config .long_term_entries < 4 ) {
133
+ destination_cache_config .long_term_entries = 4 ;
134
+ }
135
+ destination_cache_config .short_term_entries = max_cache / 2 ;
136
+ if (destination_cache_config .short_term_entries < destination_cache_config .long_term_entries ) {
137
+ destination_cache_config .short_term_entries = destination_cache_config .long_term_entries ;
138
+ }
139
+
140
+ // adjust neighbour cache
141
+ neighbour_cache_config .max_entries = max_cache ;
142
+ neighbour_cache_config .long_term_entries = max_cache / 8 ;
143
+ if (neighbour_cache_config .long_term_entries < 4 ) {
144
+ neighbour_cache_config .long_term_entries = 4 ;
145
+ }
146
+ neighbour_cache_config .short_term_entries = max_cache / 4 ;
147
+ if (neighbour_cache_config .short_term_entries < neighbour_cache_config .long_term_entries ) {
148
+ neighbour_cache_config .short_term_entries = neighbour_cache_config .long_term_entries ;
149
+ }
150
+
151
+ return 0 ;
152
+ }
153
+
154
+ int8_t ipv6_destination_cache_configure (uint16_t max_entries , uint16_t short_term_threshold , uint16_t long_term_threshold , uint16_t lifetime )
155
+ {
156
+ if ((max_entries < 4 ) || (short_term_threshold >= max_entries ) || (long_term_threshold >= short_term_threshold ) || (lifetime < 120 )) {
157
+ return -1 ;
158
+ }
159
+
160
+ destination_cache_config .max_entries = max_entries ;
161
+ destination_cache_config .short_term_entries = short_term_threshold ;
162
+ destination_cache_config .long_term_entries = long_term_threshold ;
163
+ destination_cache_config .entry_lifetime = lifetime ;
164
+
165
+ return 0 ;
166
+ }
167
+
168
+ int8_t ipv6_neighbour_cache_configure (uint16_t max_entries , uint16_t short_term_threshold , uint16_t long_term_threshold , uint16_t lifetime )
169
+ {
170
+ if ((max_entries < 4 ) || (short_term_threshold >= max_entries ) || (long_term_threshold >= short_term_threshold ) || (lifetime < 120 )) {
171
+ return -1 ;
172
+ }
173
+
174
+ neighbour_cache_config .max_entries = max_entries ;
175
+ neighbour_cache_config .short_term_entries = short_term_threshold ;
176
+ neighbour_cache_config .long_term_entries = long_term_threshold ;
177
+ neighbour_cache_config .entry_lifetime = lifetime ;
178
+
124
179
return 0 ;
125
180
}
126
181
@@ -260,7 +315,7 @@ ipv6_neighbour_t *ipv6_neighbour_lookup_or_create(ipv6_neighbour_cache_t *cache,
260
315
}
261
316
}
262
317
263
- if (count >= current_max_cache ) {
318
+ if (count >= neighbour_cache_config . max_entries ) {
264
319
entry = ns_list_get_last (& cache -> list );
265
320
ipv6_neighbour_entry_remove (cache , entry );
266
321
}
@@ -311,7 +366,7 @@ ipv6_neighbour_t *ipv6_neighbour_used(ipv6_neighbour_cache_t *cache, ipv6_neighb
311
366
{
312
367
/* Reset the GC life, if it's a GC entry */
313
368
if (entry -> type == IP_NEIGHBOUR_GARBAGE_COLLECTIBLE ) {
314
- entry -> lifetime = NCACHE_GC_AGE ;
369
+ entry -> lifetime = neighbour_cache_config . entry_lifetime ;
315
370
}
316
371
317
372
/* Move it to the front of the list */
@@ -653,7 +708,7 @@ static void ipv6_neighbour_cache_gc_periodic(ipv6_neighbour_cache_t *cache)
653
708
}
654
709
}
655
710
656
- if (gc_count <= cache_long_term (false) ) {
711
+ if (gc_count <= neighbour_cache_config . long_term_entries ) {
657
712
return ;
658
713
}
659
714
@@ -669,9 +724,9 @@ static void ipv6_neighbour_cache_gc_periodic(ipv6_neighbour_cache_t *cache)
669
724
continue ;
670
725
}
671
726
672
- if (entry -> lifetime == 0 || gc_count > cache_short_term (false) ) {
727
+ if (entry -> lifetime == 0 || gc_count > neighbour_cache_config . short_term_entries ) {
673
728
ipv6_neighbour_entry_remove (cache , entry );
674
- if (-- gc_count <= cache_long_term (false) ) {
729
+ if (-- gc_count <= neighbour_cache_config . long_term_entries ) {
675
730
break ;
676
731
}
677
732
}
@@ -876,7 +931,7 @@ ipv6_destination_t *ipv6_destination_lookup_or_create(const uint8_t *address, in
876
931
877
932
878
933
if (!entry ) {
879
- if (count > current_max_cache ) {
934
+ if (count > destination_cache_config . max_entries ) {
880
935
entry = ns_list_get_last (& ipv6_destination_cache );
881
936
ns_list_remove (& ipv6_destination_cache , entry );
882
937
ipv6_destination_release (entry );
@@ -915,7 +970,7 @@ ipv6_destination_t *ipv6_destination_lookup_or_create(const uint8_t *address, in
915
970
if (addr_ipv6_scope (address , NULL ) <= IPV6_SCOPE_LINK_LOCAL ) {
916
971
entry -> lifetime = DCACHE_GC_AGE_LL ;
917
972
} else {
918
- entry -> lifetime = DCACHE_GC_AGE ;
973
+ entry -> lifetime = destination_cache_config . entry_lifetime / DCACHE_GC_PERIOD ;
919
974
}
920
975
921
976
return entry ;
@@ -1048,7 +1103,7 @@ static void ipv6_destination_cache_gc_periodic(void)
1048
1103
#endif
1049
1104
}
1050
1105
1051
- if (gc_count <= cache_long_term (true) ) {
1106
+ if (gc_count <= destination_cache_config . long_term_entries ) {
1052
1107
return ;
1053
1108
}
1054
1109
@@ -1058,10 +1113,10 @@ static void ipv6_destination_cache_gc_periodic(void)
1058
1113
* MAX_LONG_TERM.
1059
1114
*/
1060
1115
ns_list_foreach_reverse_safe (ipv6_destination_t , entry , & ipv6_destination_cache ) {
1061
- if (entry -> lifetime == 0 || gc_count > cache_short_term (true) ) {
1116
+ if (entry -> lifetime == 0 || gc_count > destination_cache_config . short_term_entries ) {
1062
1117
ns_list_remove (& ipv6_destination_cache , entry );
1063
1118
ipv6_destination_release (entry );
1064
- if (-- gc_count <= cache_long_term (true) ) {
1119
+ if (-- gc_count <= destination_cache_config . long_term_entries ) {
1065
1120
break ;
1066
1121
}
1067
1122
}
0 commit comments