Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
map-agent
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Multi-AP
map-agent
Commits
70c9d070
Commit
70c9d070
authored
1 year ago
by
Maxim Menshikov
Browse files
Options
Downloads
Patches
Plain Diff
Installation of rules
parent
345d50d7
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/qos.c
+321
-34
321 additions, 34 deletions
src/qos.c
src/qos.h
+10
-2
10 additions, 2 deletions
src/qos.h
src/qos_internal.h
+85
-0
85 additions, 0 deletions
src/qos_internal.h
with
416 additions
and
36 deletions
src/qos.c
+
321
−
34
View file @
70c9d070
...
@@ -10,45 +10,80 @@
...
@@ -10,45 +10,80 @@
#include
<stdio.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<stdlib.h>
#include
<unistd.h>
#include
<unistd.h>
#include
<string.h>
#include
<signal.h>
#include
<arpa/inet.h>
#include
<sys/ioctl.h>
#include
<net/if_arp.h>
#include
<linux/if_bridge.h>
#ifndef _GNU_SOURCE
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#define _GNU_SOURCE
#endif
#endif
#include
<libubox/list.h>
#include
<json-c/json.h>
#include
<libubox/blobmsg.h>
#include
<libubox/blobmsg_json.h>
#include
<libubox/uloop.h>
#include
<libubox/ustream.h>
#include
<libubox/utils.h>
#include
<libubus.h>
#if (EASYMESH_VERSION >2)
#include
<openssl/err.h>
#include
<openssl/bn.h>
#include
<openssl/evp.h>
#include
<openssl/x509.h>
#include
<openssl/ec.h>
#endif
#include
<cmdu.h>
#include
<1905_tlvs.h>
#include
<1905_tlvs.h>
#include
<easymesh.h>
#include
<i1905_wsc.h>
#include
<map_module.h>
#include
<uci.h>
#include
"timer.h"
#include
"utils/1905_ubus.h"
#include
"utils/utils.h"
#include
"utils/debug.h"
#include
"utils/debug.h"
#include
"utils/liblist.h"
#include
"steer_rules.h"
#include
"steer_rules.h"
#if (EASYMESH_VERSION > 2)
#include
"dpp.h"
#endif
#include
"config.h"
#include
"nl.h"
#include
"agent.h"
#include
"qos.h"
#include
"qos_internal.h"
/* Rule types */
void
qos_rule_free
(
void
*
rule
)
enum
qos_rule_type
{
QOS_RULE_TYPE_DSCP_PCP
,
QOS_RULE_TYPE_MSCS
,
QOS_RULE_TYPE_SCS
,
QOS_RULE_TYPE_MGMT
,
};
/* Temporary rule structure which contains both SPR and DSCP parts */
typedef
struct
temp_rule
{
struct
list_head
list
;
struct
tlv_spr
spr
;
enum
qos_rule_type
type
;
union
{
struct
ieee1905_dscp_pcp_usr
dscp
;
};
}
temp_rule
;
/* Rules list */
LIST_HEAD
(
rules
);
int
qos_add_dscp_rule
(
struct
tlv_spr
*
spr
,
struct
ieee1905_dscp_pcp_usr
*
dscp_pcp
)
{
{
free
(
rule
);
}
void
qos_rule_free_all
(
struct
list_head
*
list_head
)
{
struct
temp_rule
*
p
,
*
tmp
;
list_for_each_entry_safe
(
p
,
tmp
,
list_head
,
list
)
{
qos_rule_free
(
p
);
}
}
int
qos_add_dscp_rule
(
void
*
agent
,
struct
tlv_spr
*
spr
,
struct
ieee1905_dscp_pcp_usr
*
dscp_pcp
)
{
struct
agent
*
a
=
(
struct
agent
*
)
agent
;
struct
temp_rule
*
r
;
struct
temp_rule
*
r
;
dbg
(
"%s: adding DSCP rule..."
,
__func__
);
dbg
(
"%s: adding DSCP rule...
\n
"
,
__func__
);
list_for_each_entry
(
r
,
&
rules
,
list
)
{
list_for_each_entry
(
r
,
&
a
->
qos_
rules
,
list
)
{
if
(
r
->
spr
.
rule_id
==
spr
->
rule_id
)
{
if
(
r
->
spr
.
rule_id
==
spr
->
rule_id
)
{
err
(
"%s:
adding
DSCP rule exists"
,
__func__
);
err
(
"%s: DSCP rule exists
\n
"
,
__func__
);
return
-
1
;
return
-
1
;
}
}
}
}
...
@@ -62,19 +97,272 @@ int qos_add_dscp_rule(struct tlv_spr *spr, struct ieee1905_dscp_pcp_usr *dscp_pc
...
@@ -62,19 +97,272 @@ int qos_add_dscp_rule(struct tlv_spr *spr, struct ieee1905_dscp_pcp_usr *dscp_pc
memcpy
(
&
r
->
spr
,
spr
,
sizeof
(
struct
tlv_spr
));
memcpy
(
&
r
->
spr
,
spr
,
sizeof
(
struct
tlv_spr
));
memcpy
(
&
r
->
dscp
,
dscp_pcp
,
sizeof
(
struct
ieee1905_dscp_pcp_usr
));
memcpy
(
&
r
->
dscp
,
dscp_pcp
,
sizeof
(
struct
ieee1905_dscp_pcp_usr
));
dbg
(
"%s: DSCP rule added"
,
__func__
);
dbg
(
"%s: DSCP rule added
\n
"
,
__func__
);
list_add_tail
(
&
r
->
list
,
&
rules
);
list_add_tail
(
&
r
->
list
,
&
a
->
qos_rules
);
return
0
;
}
int
qos_del_dscp_rule
(
void
*
agent
,
struct
tlv_spr
*
spr
)
{
struct
agent
*
a
=
(
struct
agent
*
)
agent
;
struct
temp_rule
*
r
;
dbg
(
"%s: removing DSCP rule...
\n
"
,
__func__
);
list_for_each_entry
(
r
,
&
a
->
qos_rules
,
list
)
{
if
(
r
->
spr
.
rule_id
==
spr
->
rule_id
)
{
list_del
(
&
r
->
list
);
dbg
(
"%s: DSCP rule removed
\n
"
,
__func__
);
return
0
;
}
}
err
(
"%s: rule is not found
\n
"
,
__func__
);
return
-
1
;
}
dscp_pcp_conv_result
dscp_pcp2qosmap
(
uint8_t
dscp_pcp
[
64
],
char
*
qos_map
,
size_t
qos_map_len
)
{
/* Internal constants */
#define PCP_COUNT (8)
#define DSCP_PCP_MAX (64)
#define DSCP_UP_EXC_MAX (21)
#define RANGE_MIN (0)
#define RANGE_MAX (1)
#define RANGE_TOTAL (2)
#define TMP_BUF_LEN (50)
#define DSCP_NEUTRAL (255)
dscp_pcp_conv_result
rc
=
DSCP_PCP_CONV_RESULT_OK
;
/* pcp -> dscp usage table */
uint8_t
pcp_dscp
[
PCP_COUNT
][
DSCP_PCP_MAX
];
/* Minimal and maximal DSCPs for PCP */
uint8_t
pcp_dscp_min
[
PCP_COUNT
]
=
{
DSCP_NEUTRAL
};
uint8_t
pcp_dscp_max
[
PCP_COUNT
]
=
{
DSCP_NEUTRAL
};
/* DSCP exceptions */
uint8_t
dscp_up
[
DSCP_UP_EXC_MAX
][
2
];
size_t
total_du
=
0
;
size_t
i
,
j
;
size_t
final_len
;
memset
(
pcp_dscp
,
0
,
sizeof
(
pcp_dscp
));
/* Convert DSCP->PCP to PCP->DSCP usage table */
for
(
i
=
0
;
i
<
DSCP_PCP_MAX
;
++
i
)
{
uint8_t
pcp
=
dscp_pcp
[
i
];
uint8_t
dscp
=
i
;
pcp_dscp
[
pcp
][
dscp
]
=
1
;
}
/* Find the biggest ranges of used DSCPs for PCPs */
for
(
i
=
0
;
i
<
PCP_COUNT
;
++
i
)
{
uint8_t
ranges
[
64
][
3
];
uint8_t
total_ranges
=
0
;
int
inside
=
0
;
uint8_t
range_biggest_val
;
int
range_biggest_index
=
-
1
;
memset
(
ranges
,
0
,
sizeof
(
ranges
));
for
(
j
=
0
;
j
<
DSCP_PCP_MAX
;
++
j
)
{
if
(
pcp_dscp
[
i
][
j
])
{
if
(
inside
==
0
)
{
inside
=
1
;
ranges
[
total_ranges
][
RANGE_MIN
]
=
j
;
ranges
[
total_ranges
][
RANGE_MAX
]
=
j
;
ranges
[
total_ranges
][
RANGE_TOTAL
]
=
1
;
if
(
range_biggest_index
==
-
1
)
{
range_biggest_index
=
total_ranges
;
range_biggest_val
=
1
;
}
total_ranges
++
;
}
else
{
ranges
[
total_ranges
-
1
][
RANGE_MAX
]
=
j
;
ranges
[
total_ranges
-
1
][
RANGE_TOTAL
]
++
;
if
(
range_biggest_val
<
ranges
[
total_ranges
-
1
][
RANGE_TOTAL
])
{
range_biggest_index
=
total_ranges
-
1
;
range_biggest_val
++
;
}
}
}
else
{
if
(
inside
==
1
)
{
inside
=
0
;
}
}
}
if
(
range_biggest_index
!=
-
1
)
{
pcp_dscp_min
[
i
]
=
ranges
[
range_biggest_index
][
RANGE_MIN
];
pcp_dscp_max
[
i
]
=
ranges
[
range_biggest_index
][
RANGE_MAX
];
}
else
{
pcp_dscp_min
[
i
]
=
DSCP_NEUTRAL
;
pcp_dscp_max
[
i
]
=
DSCP_NEUTRAL
;
}
}
/* Find exceptions that don't belong to [DSCP_min, DSCP_max] range */
for
(
i
=
0
;
i
<
DSCP_PCP_MAX
;
++
i
)
{
uint8_t
pcp
=
dscp_pcp
[
i
];
uint8_t
dscp
=
i
;
if
(
dscp
<
pcp_dscp_min
[
pcp
]
||
dscp
>
pcp_dscp_max
[
pcp
])
{
dscp_up
[
total_du
][
0
]
=
dscp
;
dscp_up
[
total_du
][
1
]
=
pcp
;
total_du
++
;
if
(
total_du
==
DSCP_UP_EXC_MAX
)
{
rc
=
DSCP_PCP_CONV_RESULT_OK_TOO_MANY_EXC
;
break
;
}
}
}
/* Write out pcp_X_dscp_min,pcp_X_dscp_max */
final_len
=
0
;
for
(
i
=
0
;
i
<
total_du
;
++
i
)
{
char
pair
[
TMP_BUF_LEN
];
/*
* No need for bounds check - result length can't exceed the buffer
* length
*/
sprintf
(
pair
,
"%d,%d,"
,
dscp_up
[
i
][
0
],
dscp_up
[
i
][
1
]);
final_len
+=
strlen
(
pair
);
if
(
final_len
>
qos_map_len
)
{
rc
=
DSCP_PCP_CONV_RESULT_TOO_LONG
;
break
;
}
}
if
(
rc
!=
DSCP_PCP_CONV_RESULT_OK
&&
rc
!=
DSCP_PCP_CONV_RESULT_OK_TOO_MANY_EXC
)
return
rc
;
/* Write out PCP_x_DSCP_min, PCP_x_DSCP_max */
for
(
i
=
0
;
i
<
PCP_COUNT
;
++
i
)
{
char
pair
[
TMP_BUF_LEN
];
/*
* No need for bounds check - result length can't exceed the buffer
* length
*/
sprintf
(
pair
,
"%s%d,%d"
,
(
i
!=
0
||
total_du
==
0
)
?
","
:
""
,
pcp_dscp_min
[
i
],
pcp_dscp_max
[
i
]);
final_len
+=
strlen
(
pair
);
if
(
final_len
>
qos_map_len
)
{
rc
=
DSCP_PCP_CONV_RESULT_TOO_LONG
;
break
;
}
}
#undef PCP_COUNT
#undef DSCP_PCP_MAX
#undef DSCP_UP_EXC_MAX
#undef RANGE_MIN
#undef RANGE_MAX
#undef RANGE_TOTAL
#undef TMP_BUF_LEN
return
rc
;
}
int
qos_apply_dscp_rules
(
void
*
agent
)
{
dscp_pcp_conv_result
rc
;
struct
agent
*
a
=
(
struct
agent
*
)
agent
;
struct
temp_rule
*
r
;
struct
netif_fhcfg
*
fcfg
=
NULL
;
dbg
(
"%s: applying DSCP rules...
\n
"
,
__func__
);
list_for_each_entry
(
r
,
&
a
->
qos_rules
,
list
)
{
char
str
[
512
]
=
{
'\0'
};
if
(
r
->
spr
.
output
!=
0x08
)
continue
;
rc
=
dscp_pcp2qosmap
(
r
->
dscp
.
dscp_pcp
,
str
,
sizeof
(
str
)
-
1
);
if
(
rc
!=
DSCP_PCP_CONV_RESULT_OK
&&
rc
!=
DSCP_PCP_CONV_RESULT_OK_TOO_MANY_EXC
)
{
err
(
"%s: wrong QoS map
\n
"
,
__func__
);
continue
;
}
list_for_each_entry
(
fcfg
,
&
a
->
cfg
.
fhlist
,
list
)
{
runCmd
(
"hostapd_cli -i %s set_qos_map_set %s"
,
fcfg
->
name
,
str
);
}
dbg
(
"%s: DSCP rule applied: %s
\n
"
,
__func__
,
str
);
}
qos_sync_rules_to_nodes
(
agent
);
dbg
(
"%s: done with DSCP rules
\n
"
,
__func__
);
return
0
;
}
int
qos_sync_rules_to_nodes
(
void
*
agent
)
{
struct
agent
*
a
=
(
struct
agent
*
)
agent
;
struct
netif_fhcfg
*
fcfg
=
NULL
;
struct
node
*
n
=
NULL
;
list_for_each_entry
(
n
,
&
a
->
nodelist
,
list
)
{
char
mac
[
50
];
hwaddr_ntoa
(
n
->
alid
,
mac
);
list_for_each_entry
(
fcfg
,
&
a
->
cfg
.
fhlist
,
list
)
{
runCmd
(
"hostapd_cli -i %s send_qos_map_conf %s"
,
fcfg
->
name
,
mac
);
}
}
return
0
;
return
0
;
}
}
int
qos_get_rules
(
void
)
int
qos_get_rules
(
void
*
agent
)
{
{
struct
agent
*
a
=
(
struct
agent
*
)
agent
;
struct
temp_rule
*
r
;
struct
temp_rule
*
r
;
int
nr
=
0
;
int
nr
=
0
;
info
(
"Registered QoS rules:
"
);
info
(
"Registered QoS rules:
\n
"
);
list_for_each_entry
(
r
,
&
rules
,
list
)
{
list_for_each_entry
(
r
,
&
a
->
qos_
rules
,
list
)
{
info
(
"[%d] add %d prec %doutput %d always %d"
,
info
(
"[%d] add %d prec %doutput %d always %d
\n
"
,
r
->
spr
.
rule_id
,
r
->
spr
.
rule_id
,
r
->
spr
.
add_remove
,
r
->
spr
.
add_remove
,
r
->
spr
.
precedence
,
r
->
spr
.
precedence
,
...
@@ -82,7 +370,6 @@ int qos_get_rules(void)
...
@@ -82,7 +370,6 @@ int qos_get_rules(void)
r
->
spr
.
always_match
);
r
->
spr
.
always_match
);
nr
++
;
nr
++
;
}
}
info
(
"
\n
"
);
return
nr
;
return
nr
;
}
}
This diff is collapsed.
Click to expand it.
src/qos.h
+
10
−
2
View file @
70c9d070
...
@@ -11,7 +11,15 @@
...
@@ -11,7 +11,15 @@
#include
<libubox/list.h>
#include
<libubox/list.h>
#include
<1905_tlvs.h>
#include
<1905_tlvs.h>
int
qos_add_dscp_rule
(
struct
tlv_spr
*
spr
,
struct
ieee1905_dscp_pcp_usr
*
dscp_pcp
);
void
qos_rule_free
(
void
*
rule
);
int
qos_get_rules
(
void
);
void
qos_rule_free_all
(
struct
list_head
*
list
);
int
qos_add_dscp_rule
(
void
*
a
,
struct
tlv_spr
*
spr
,
struct
ieee1905_dscp_pcp_usr
*
dscp_pcp
);
int
qos_del_dscp_rule
(
void
*
a
,
struct
tlv_spr
*
spr
);
int
qos_apply_dscp_rules
(
void
*
a
);
int
qos_sync_rules_to_nodes
(
void
*
agent
);
int
qos_get_rules
(
void
*
a
);
#endif
#endif
This diff is collapsed.
Click to expand it.
src/qos_internal.h
0 → 100644
+
85
−
0
View file @
70c9d070
#ifndef MAPAGENT_QOS_INTERNAL_H
#define MAPAGENT_QOS_INTERNAL_H
#include
<stdio.h>
#include
<stdlib.h>
#include
<unistd.h>
#include
<signal.h>
#include
<arpa/inet.h>
#include
<sys/ioctl.h>
#include
<net/if_arp.h>
#include
<linux/if_bridge.h>
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include
<json-c/json.h>
#include
<libubox/blobmsg.h>
#include
<libubox/blobmsg_json.h>
#include
<libubox/uloop.h>
#include
<libubox/ustream.h>
#include
<libubox/utils.h>
#include
<libubus.h>
#if (EASYMESH_VERSION >2)
#include
<openssl/err.h>
#include
<openssl/bn.h>
#include
<openssl/evp.h>
#include
<openssl/x509.h>
#include
<openssl/ec.h>
#endif
#include
<cmdu.h>
#include
<1905_tlvs.h>
#include
<easymesh.h>
#include
<i1905_wsc.h>
#include
<map_module.h>
#include
<uci.h>
#include
"timer.h"
#include
"utils/1905_ubus.h"
#include
"utils/utils.h"
#include
"utils/debug.h"
#include
"utils/liblist.h"
#include
"steer_rules.h"
#if (EASYMESH_VERSION > 2)
#include
"dpp.h"
#endif
#include
"config.h"
#include
"nl.h"
#include
"agent.h"
#include
"qos.h"
/* Rule types */
enum
qos_rule_type
{
QOS_RULE_TYPE_DSCP_PCP
,
/**< DSCP policy type */
QOS_RULE_TYPE_MSCS
,
/**< MSCS rule */
QOS_RULE_TYPE_SCS
,
/**< SCS rule */
QOS_RULE_TYPE_MGMT
,
/**< Management rule */
};
/* Temporary rule structure which contains both SPR and DSCP parts */
typedef
struct
temp_rule
{
struct
list_head
list
;
/**< List head */
struct
tlv_spr
spr
;
/**< Service Prioritization Rule */
enum
qos_rule_type
type
;
/**< Rule Type */
union
{
struct
ieee1905_dscp_pcp_usr
dscp
;
/**< DSCP rule - valid only in
case of
QOS_RULE_TYPE_DSCP_PCP rule
type */
};
}
temp_rule
;
/* DSCP-PCP -> hostapd format conversion results */
typedef
enum
dscp_pcp_conv_result
{
DSCP_PCP_CONV_RESULT_OK
,
/**< Conversion finished well */
DSCP_PCP_CONV_RESULT_OK_TOO_MANY_EXC
,
/**< Conversion finished well,
but too many exceptions */
DSCP_PCP_CONV_RESULT_TOO_LONG
,
/**< Too long result that didn't
fit the output buffer */
}
dscp_pcp_conv_result
;
#endif
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment