/* Set the values to the specific association */
if (asoc) {
- if (assocparams.sasoc_asocmaxrxt != 0)
+ if (assocparams.sasoc_asocmaxrxt != 0) {
+ __u32 path_sum = 0;
+ int paths = 0;
+ struct list_head *pos;
+ struct sctp_transport *peer_addr;
+
+ list_for_each(pos, &asoc->peer.transport_addr_list) {
+ peer_addr = list_entry(pos,
+ struct sctp_transport,
+ transports);
+ path_sum += peer_addr->pathmaxrxt;
+ paths++;
+ }
+
+ /* Only validate asocmaxrxt if we have more then
+ * one path/transport. We do this because path
+ * retransmissions are only counted when we have more
+ * then one path.
+ */
+ if (paths > 1 &&
+ assocparams.sasoc_asocmaxrxt > path_sum)
+ return -EINVAL;
+
asoc->max_retrans = assocparams.sasoc_asocmaxrxt;
+ }
+
if (assocparams.sasoc_cookie_life != 0) {
asoc->cookie_life.tv_sec =
assocparams.sasoc_cookie_life / 1000;